如何构建一个Koa后端项目脚手架的完整步骤指南?

2026-04-09 19:422阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计3671个文字,预计阅读时间需要15分钟。

如何构建一个Koa后端项目脚手架的完整步骤指南?

一、背景及结合当前node比较火的三大框架,Express、Koa、Egg。

作者之前用的Express,后面发现回调太多,实在忍受不了。实际开发中觉得太无趣了。终于有一天去尝试了Koa来进行开发,发现实际开发实在太爽了。

一、背景

结合当前的node比较火的三大框架,Express、Koa、egg。笔者之前用的Express,后面发现回调把我搞死了,实在太无奈了。终于有一天去尝试了Koa来进行开发,发现实在太舒服了。ES6语法支持很多,同步模式也很到位,但是在学习koa的过程中,发现基本的基础知识都了解了,也按照官方的文档走了一遍,但发现好像无从下手。感觉开发过程中,分层不太明显,业务逻辑简单还好,一多麻烦就来了。查看了资料后,有一个koa的脚手架叫做 koa-generator ,马上尝试后发现不是我想要的模板。看来github已经有2年没有维护了,koa2一些新特性也没有加上,感觉有点快落伍了。于是结合其他人的模式,也避免后面自己过多的重复造轮子。编写一个Koa项目的初始模板。这个模板主要的功能集成了Logger、Router、JWT、Mongoose、redis、PM2等模块,还有部分的中间件集合,该模板对于简单的后台项目来说基本够用了,没有考虑高并发处理,后期会继续完善。对于初学者来说,可以快速的新项目开发,在开始之前先好好看下面的解读。

二、目录结构

下面的目录是该模板基础目录结构,后面的章节会对每一个目录的配置进行介绍,让大家在开发中对项目的结构比较清晰,出了问题容易定位。

├─.gitignore // 忽略文件配置 ├─app.js // 应用入口 ├─config.js // 公共配置文件 ├─ecosystem.config.js // pm2配置文件 ├─package.json // 依赖文件配置 ├─README.md // README.md文档 ├─routes // 路由 | ├─private.js // 校验接口 | └public.js // 公开接口 ├─models // 数据库配置及模型 | ├─index.js // 数据库配置 | └user.js // 用户的schema文件 ├─middlewares // 中间件 | ├─cors.js // 跨域中间件 | ├─jwt.js // jwt中间件 | ├─logger.js // 日志打印中间件 | └response.js // 响应及异常处理中间件 ├─logs // 日志目录 | ├─koa-template.log | └koa-template.log-2019-05-28 ├─lib // 工具库 | ├─error.js // 异常处理 | └mongoDB.js // mongoDB配置 ├─controllers // 操作数据库及业务逻辑 | ├─index.js // 配置 | ├─login.js // 登录 | └test.js // 测试 ├─bin // 启动目录 | └www // 启动文件配置

bin文件

bin文件目录中,只有一个文件,即为www,因为我们后端的项目基本上是在Linux上进行运行的,其实我们不必去担心文件的后缀是什么,只需知道该文件是可执行文件还是不可执行文件就行了。这个文件有什么用呢?其实我们这个文件是用来部署的时候可以启动我们一整个后端程序,也就是我们前端中的集成的运行环境。我们的运行、关闭、重启都在这文件进行即可。基本代码如下:

#!/usr/bin/env node /** * Module dependencies. */ const app = require('../app') const localhost:8080 这个域名的请求了 // ctx.set("Access-Control-Allow-Origin", "localhost:8080"); // 设置所允许的HTTP请求方法 ctx.set("Access-Control-Allow-Methods", "OPTIONS, GET, PUT, POST, DELETE"); // 字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段. ctx.set("Access-Control-Allow-Headers", "x-requested-with, accept, origin, content-type"); // 服务器收到请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。 // Content-Type表示具体请求中的媒体类型信息 ctx.set("Content-Type", "application/json;charset=utf-8"); // 该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。 // 当设置成允许请求携带cookie时,需要保证"Access-Control-Allow-Origin"是服务器有的域名,而不能是"*"; ctx.set("Access-Control-Allow-Credentials", true); // 该字段可选,用来指定本次预检请求的有效期,单位为秒。 // 当请求方法是PUT或DELETE等特殊方法或者Content-Type字段的类型是application/json时,服务器会提前发送一次请求进行验证 // 下面的的设置只本次验证的有效时间,即在该时间段内服务端可以不用进行验证 ctx.set("Access-Control-Max-Age", 300); /* CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段: Cache-Control、 Content-Language、 Content-Type、 Expires、 Last-Modified、 Pragma。 */ // 需要获取其他字段时,使用Access-Control-Expose-Headers, // getResponseHeader('myData')可以返回我们所需的值 //www.rails365.net/articles/cors-jin-jie-expose-headers-wu ctx.set("Access-Control-Expose-Headers", "myData"); await next(); })

相对用得较多是的大神封装好得koa-cors中间件,可以自行查看npm上得文档,在这个项目中用的就是koa-cors的中间件,基本的配置写在cors.js里面了,再通过中间件进行引用。注意要写在router前面,避免在没有进行跨域配置前就去请求接口。

app.js中的引用,记得安装引入koa-cors

// cors app.use(cors(corsHandler))

'use strict' const corsHandler = { origin: function (ctx) { if (ctx.url === '/test') { // 这里可以配置不运行跨域的接口地址 return false; } return '*'; }, exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'], maxAge: 5, credentials: true, allowMethods: ['GET', 'POST', 'DELETE'], allowHeaders: ['Content-Type', 'Authorization', 'Accept'], } module.exports = { corsHandler }

koa-helmet 中间件

koa-helmet 可以帮助你的 app 抵御一些比较常见的安全 web 安全隐患,它其实是将 9 个安全中间件集中到了一起,做了合并,大部分都是对于 " + config.mongoDB.host + ":" + config.mongoDB.port + "/" + config.mongoDB.database; var mongo = mongoose.createConnection(url); //创建一个数据库连接 let db = { mongoose: mongoose, mongo: mongo, models: {} }; // 错误 mongo.on('error', function (err) { logger.error(new Error(err)); }); // 开启 mongo.once('open', function () { logger.info("mongo is opened"); }); // 整合models文件下的其他js文件 fs.readdirSync(__dirname) .filter(function (file) { return (file.indexOf(".") !== 0) && (file !== "index.js"); }).forEach(function (file) { var modelFile = require(path.join(__dirname, file)); var schema = new mongoose.Schema(modelFile.schema); db.models[modelFile.name] = mongo.model(modelFile.name, schema, modelFile.name); }); // 根据name选择model db.getModel = function (name) { return this.models[name]; }; module.exports = db;

代码中的链接部分一看基本就明白了,可是 models 部分怎么看不出所以然。其实是模块化开发的一部分,这里是为了整合models文件下的其他js文件,方便开发者使用,不用每写一个文件就要进行引入和导出。

初始情况下, models 引入只需 mongoose.model('名称', schema); 并将其暴露出去,即可对数据库进行操作。

如何构建一个Koa后端项目脚手架的完整步骤指南?

fs.readdirSync(__dirname) .filter(function (file) { return (file.indexOf(".") !== 0) && (file !== "index.js"); }).forEach(function (file) { var modelFile = require(path.join(__dirname, file)); var schema = new mongoose.Schema(modelFile.schema); db.models[modelFile.name] = mongo.model(modelFile.name, schema, modelFile.name); });

在这个文件内,我们做了这样一件事:读取 models 目录下所有文件名不为 index.js 且以 .js 为后缀名的文件,使用 require 进行引用,并将其整合为一个 schema对象后再引入到models并且暴露出去给操作数据库。这样子做的好处是,在项目越来越庞大以后,如果我们需要添加新的 schema ,只需直接在 models 目录下新建 .js 文件即可,则不用再进行引入的关系操作

由于有了上一步的操作,我们后面直接新增一个schema的配置文件即可。index.js会自动的引入并暴露出model

'use strict' module.exports = { name: "user", schema: { uuid: String, // UUID userName: String, // 用户名 password: String, // 密码 } };

我们使用时可以这样操作,

const User = require('../models/index').getModel('user') const user = await User.findOne({userName: userName})

PM2配置

PM2是可以用于生产环境的Nodejs的进程管理工具,并且它内置一个负载均衡。它不仅可以保证服务不会中断一直在线,并且提供0秒reload功能,还有其他一系列进程管理、监控功能。并且使用起来非常简单。pm2的官方文档已经进行详细的配置说明,在这里就不进行一一简述,主要讲的时我的koa项目怎样配合PM2进行相关管理或者说部署。PM2常用命令需要用的时候可以进行查看,没必要去背,用多就熟悉了。也可以结合在package.json里面,用自定义命令运行。我们在 package.jsonscript 配置和初始化文件 ecosystem.config.js 进行了多环境运行的配置,我们可以根据需要进行切换环境。

package.json 文件添加如下:

"scripts": { "start": "node ./bin/www", "dev": "pm2 start ecosystem.config.js --env dev", "test": "pm2 start ecosystem.config.js --env test", "pro": "pm2 start ecosystem.config.js --env pro", "logs": "pm2 logs", "stop": "pm2 stop ecosystem.config.js" },

其中的

npm run start: 直接跑www文件,可用于调试
npm run dev: 开发环境
npm run test:测试环境
npm run pro:生产环境
npm run logs: 查看pm2的日志
npm run stop: 停止pm2服务

新增 ecosystem.config.js 文件:

module.exports = { apps : [{ name: 'API', script: './bin/www', // Options reference: pm2.io/doc/en/runtime/reference/ecosystem-file/ args: 'one two', instances: 1, autorestart: true, watch: true, ignore_watch: [ // 不用监听的文件 'node_modules', 'logs' ], max_memory_restart: '1G', env_pro: { "NODE_ENV": "production", "REMOTE_ADDR": "" }, env_dev: { "NODE_ENV": "development", "REMOTE_ADDR": "" }, env_test: { "NODE_ENV": "test", "REMOTE_ADDR": "" } }] };

这个文件主要是对pm2的基本配置,不用每次都进行配置,直接在文件进行改动即可。我们需要关注的是可以在 env 中,增加我们需要的环境及变量即可,文件中的 watch 属性是可以配置监听文件改动后,自动重启项目,比较好用。如果想忽略某一个文件夹的变动可以 ignore_watch ,更多的配置如果有兴趣的小伙伴可以查看官方文档的文档说明。

路由配置

该目录下存放路由基本配置,有 privatepublic 两个文件,引入路由后,我们对其前缀做了处理, router.prefix('/api') 在每一个请求的时候都需要带上这个前缀,抽出来也是为了服务目录的改变,可以直接更改即可,做了全局的操作。每一个路由都必须暴露出去,这样在app.js文件中使用该中间件。 publicRouter.allowedMethods() 根据 ctx.status 设置 response 响应头

// Routes app.use(publicRouter.routes(), publicRouter.allowedMethods()) app.use(privateRouter.routes(), privateRouter.allowedMethods())

private :该文件下的路由是需要通过jwt验证的,才能进行访问。前面我们做了jwt的中间件,我们直接引入即可 router.use(jwtMiddleware) 记得要放在请求路由的前面,才能保证每次都经过它。

'use strict' const Router = require('koa-router') const controllers = require('../controllers') const jwtMiddleware = require('../middlewares/jwt') const router = new Router() router.prefix('/api') router.use(jwtMiddleware) router.get('/test', controllers.test.test) module.exports = router

public :该文件与上面相反,主要用来不进行登录的校验,也就是我们常用的登录、注册等不需要验证的接口。

'use strict' const Router = require('koa-router') const controllers = require('../controllers') const router = new Router() router.prefix('/api') router.post('/login', controllers.login.login) module.exports = router

为什么我们没在这里处理业务逻辑呢?其实这里是遵循了MVC的思想,进行了分离。把数据库的操作放到了controllers文件中。这如果我们接口一多,不会显示得特别混乱。下面我们就来讲这个文件。

controllers文件

为了让整个项目更为模块化,该目录下主要是处理对应的路由的回调函数,一般我们不会在router文件中去操作数据库和逻辑操作等步骤,这里采用 routes 和 controller 分开,在方便代码的查看同时,也方便代码的维护和开发。

index.js文件:

该文件与models中的index.js文件中的集合该目录下的文件类似,这里是将其他文件导出统一到index暴露出去。

'use strict' const fs = require('fs') const files = fs.readdirSync(__dirname).filter(file => file !== 'index.js') const controllers = {} for (const file of files) { if (file.toLowerCase().endsWith('js')) { const controller = require(`./${file}`) controllers[`${file.replace(/\.js/, '')}`] = controller } } module.exports = controllers

其他文件的编写可以按照下面基本框架进行,在这里会用到前面封装好的业务,例如数据库操作、响应、jwt等操作。大家可以认真看以下代码分析一下。

'use strict' const jwt = require('jsonwebtoken') const config = require('../config') const User = require('../models/index').getModel('user') const login = {} login.login = async (ctx, next) => { const {userName, password} = ctx.request.body const user = await User.findOne({userName: userName}) if (!user) { ctx.result = '' ctx.msg = '用户不存在' } else { ctx.result = jwt.sign({ data: user._id, // 设置 token 过期时间 exp: Math.floor(Date.now() / 1000) + (60 * 60), // 60 seconds * 60 minutes = 1 hour }, config.secret) } return next() } module.exports = login

config.js文件

该文件主要用来存放全局的配置,如果一个项目中没有全局的配置,那么一个地方改动牵动的其他地方很多,这样很不利于工作效率,在开发过程中,我们一般会把常用的都放在这个文件,例如:数据库参数,端口,密钥,全局变量等。看自己的需求适当的更改。该文件将变量进行了暴露,引用时进行require即可。

'use strict' const path = require('path') module.exports = { port: '3001', secret: 'secret', publicDir: path.resolve(__dirname, './public'), logPath: path.resolve(__dirname, './logs/koa-template.log'), mongoDB: { database: 'mall', username: 'root', password: 'root', host: '127.0.0.1', port: 27017 } }

package.json文件

每个Nodejs项目的根目录下面,一般都会有一个package.json文件。该文件可以由npm init生成,定义了项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)。 package.json文件内部就是一个JSON对象,该对象的每一个成员就是当前项目的一项设置。我们也可在里面配置我们的 npm run XXX 的命令,大家可以根据需求进行配置。这是这项目需要用到的package.json文件。

{ "name": "koa-template", "version": "0.1.0", "author": "bayi", "private": true, "scripts": { "start": "node ./bin/www", "dev": "pm2 start ecosystem.config.js --env dev", "test": "pm2 start ecosystem.config.js --env test", "pro": "pm2 start ecosystem.config.js --env pro", "logs": "pm2 logs", "stop": "pm2 stop ecosystem.config.js" }, "dependencies": { "koa": "^2.6.2", "koa-bodyparser": "^4.2.1", "koa-helmet": "^4.1.0", "koa-jwt": "^3.5.1", "koa-router": "^7.4.0", "koa-static-cache": "^5.1.2", "koa2-cors": "^2.0.6", "log4js": "^3.0.6", "mongoose": "^5.5.5" } }

三、其他

####github地址:

github.com/bayi-lzp/koa-template (star! star!star!)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自由互联。

标签:方法步骤

本文共计3671个文字,预计阅读时间需要15分钟。

如何构建一个Koa后端项目脚手架的完整步骤指南?

一、背景及结合当前node比较火的三大框架,Express、Koa、Egg。

作者之前用的Express,后面发现回调太多,实在忍受不了。实际开发中觉得太无趣了。终于有一天去尝试了Koa来进行开发,发现实际开发实在太爽了。

一、背景

结合当前的node比较火的三大框架,Express、Koa、egg。笔者之前用的Express,后面发现回调把我搞死了,实在太无奈了。终于有一天去尝试了Koa来进行开发,发现实在太舒服了。ES6语法支持很多,同步模式也很到位,但是在学习koa的过程中,发现基本的基础知识都了解了,也按照官方的文档走了一遍,但发现好像无从下手。感觉开发过程中,分层不太明显,业务逻辑简单还好,一多麻烦就来了。查看了资料后,有一个koa的脚手架叫做 koa-generator ,马上尝试后发现不是我想要的模板。看来github已经有2年没有维护了,koa2一些新特性也没有加上,感觉有点快落伍了。于是结合其他人的模式,也避免后面自己过多的重复造轮子。编写一个Koa项目的初始模板。这个模板主要的功能集成了Logger、Router、JWT、Mongoose、redis、PM2等模块,还有部分的中间件集合,该模板对于简单的后台项目来说基本够用了,没有考虑高并发处理,后期会继续完善。对于初学者来说,可以快速的新项目开发,在开始之前先好好看下面的解读。

二、目录结构

下面的目录是该模板基础目录结构,后面的章节会对每一个目录的配置进行介绍,让大家在开发中对项目的结构比较清晰,出了问题容易定位。

├─.gitignore // 忽略文件配置 ├─app.js // 应用入口 ├─config.js // 公共配置文件 ├─ecosystem.config.js // pm2配置文件 ├─package.json // 依赖文件配置 ├─README.md // README.md文档 ├─routes // 路由 | ├─private.js // 校验接口 | └public.js // 公开接口 ├─models // 数据库配置及模型 | ├─index.js // 数据库配置 | └user.js // 用户的schema文件 ├─middlewares // 中间件 | ├─cors.js // 跨域中间件 | ├─jwt.js // jwt中间件 | ├─logger.js // 日志打印中间件 | └response.js // 响应及异常处理中间件 ├─logs // 日志目录 | ├─koa-template.log | └koa-template.log-2019-05-28 ├─lib // 工具库 | ├─error.js // 异常处理 | └mongoDB.js // mongoDB配置 ├─controllers // 操作数据库及业务逻辑 | ├─index.js // 配置 | ├─login.js // 登录 | └test.js // 测试 ├─bin // 启动目录 | └www // 启动文件配置

bin文件

bin文件目录中,只有一个文件,即为www,因为我们后端的项目基本上是在Linux上进行运行的,其实我们不必去担心文件的后缀是什么,只需知道该文件是可执行文件还是不可执行文件就行了。这个文件有什么用呢?其实我们这个文件是用来部署的时候可以启动我们一整个后端程序,也就是我们前端中的集成的运行环境。我们的运行、关闭、重启都在这文件进行即可。基本代码如下:

#!/usr/bin/env node /** * Module dependencies. */ const app = require('../app') const localhost:8080 这个域名的请求了 // ctx.set("Access-Control-Allow-Origin", "localhost:8080"); // 设置所允许的HTTP请求方法 ctx.set("Access-Control-Allow-Methods", "OPTIONS, GET, PUT, POST, DELETE"); // 字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段. ctx.set("Access-Control-Allow-Headers", "x-requested-with, accept, origin, content-type"); // 服务器收到请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。 // Content-Type表示具体请求中的媒体类型信息 ctx.set("Content-Type", "application/json;charset=utf-8"); // 该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。 // 当设置成允许请求携带cookie时,需要保证"Access-Control-Allow-Origin"是服务器有的域名,而不能是"*"; ctx.set("Access-Control-Allow-Credentials", true); // 该字段可选,用来指定本次预检请求的有效期,单位为秒。 // 当请求方法是PUT或DELETE等特殊方法或者Content-Type字段的类型是application/json时,服务器会提前发送一次请求进行验证 // 下面的的设置只本次验证的有效时间,即在该时间段内服务端可以不用进行验证 ctx.set("Access-Control-Max-Age", 300); /* CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段: Cache-Control、 Content-Language、 Content-Type、 Expires、 Last-Modified、 Pragma。 */ // 需要获取其他字段时,使用Access-Control-Expose-Headers, // getResponseHeader('myData')可以返回我们所需的值 //www.rails365.net/articles/cors-jin-jie-expose-headers-wu ctx.set("Access-Control-Expose-Headers", "myData"); await next(); })

相对用得较多是的大神封装好得koa-cors中间件,可以自行查看npm上得文档,在这个项目中用的就是koa-cors的中间件,基本的配置写在cors.js里面了,再通过中间件进行引用。注意要写在router前面,避免在没有进行跨域配置前就去请求接口。

app.js中的引用,记得安装引入koa-cors

// cors app.use(cors(corsHandler))

'use strict' const corsHandler = { origin: function (ctx) { if (ctx.url === '/test') { // 这里可以配置不运行跨域的接口地址 return false; } return '*'; }, exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'], maxAge: 5, credentials: true, allowMethods: ['GET', 'POST', 'DELETE'], allowHeaders: ['Content-Type', 'Authorization', 'Accept'], } module.exports = { corsHandler }

koa-helmet 中间件

koa-helmet 可以帮助你的 app 抵御一些比较常见的安全 web 安全隐患,它其实是将 9 个安全中间件集中到了一起,做了合并,大部分都是对于 " + config.mongoDB.host + ":" + config.mongoDB.port + "/" + config.mongoDB.database; var mongo = mongoose.createConnection(url); //创建一个数据库连接 let db = { mongoose: mongoose, mongo: mongo, models: {} }; // 错误 mongo.on('error', function (err) { logger.error(new Error(err)); }); // 开启 mongo.once('open', function () { logger.info("mongo is opened"); }); // 整合models文件下的其他js文件 fs.readdirSync(__dirname) .filter(function (file) { return (file.indexOf(".") !== 0) && (file !== "index.js"); }).forEach(function (file) { var modelFile = require(path.join(__dirname, file)); var schema = new mongoose.Schema(modelFile.schema); db.models[modelFile.name] = mongo.model(modelFile.name, schema, modelFile.name); }); // 根据name选择model db.getModel = function (name) { return this.models[name]; }; module.exports = db;

代码中的链接部分一看基本就明白了,可是 models 部分怎么看不出所以然。其实是模块化开发的一部分,这里是为了整合models文件下的其他js文件,方便开发者使用,不用每写一个文件就要进行引入和导出。

初始情况下, models 引入只需 mongoose.model('名称', schema); 并将其暴露出去,即可对数据库进行操作。

如何构建一个Koa后端项目脚手架的完整步骤指南?

fs.readdirSync(__dirname) .filter(function (file) { return (file.indexOf(".") !== 0) && (file !== "index.js"); }).forEach(function (file) { var modelFile = require(path.join(__dirname, file)); var schema = new mongoose.Schema(modelFile.schema); db.models[modelFile.name] = mongo.model(modelFile.name, schema, modelFile.name); });

在这个文件内,我们做了这样一件事:读取 models 目录下所有文件名不为 index.js 且以 .js 为后缀名的文件,使用 require 进行引用,并将其整合为一个 schema对象后再引入到models并且暴露出去给操作数据库。这样子做的好处是,在项目越来越庞大以后,如果我们需要添加新的 schema ,只需直接在 models 目录下新建 .js 文件即可,则不用再进行引入的关系操作

由于有了上一步的操作,我们后面直接新增一个schema的配置文件即可。index.js会自动的引入并暴露出model

'use strict' module.exports = { name: "user", schema: { uuid: String, // UUID userName: String, // 用户名 password: String, // 密码 } };

我们使用时可以这样操作,

const User = require('../models/index').getModel('user') const user = await User.findOne({userName: userName})

PM2配置

PM2是可以用于生产环境的Nodejs的进程管理工具,并且它内置一个负载均衡。它不仅可以保证服务不会中断一直在线,并且提供0秒reload功能,还有其他一系列进程管理、监控功能。并且使用起来非常简单。pm2的官方文档已经进行详细的配置说明,在这里就不进行一一简述,主要讲的时我的koa项目怎样配合PM2进行相关管理或者说部署。PM2常用命令需要用的时候可以进行查看,没必要去背,用多就熟悉了。也可以结合在package.json里面,用自定义命令运行。我们在 package.jsonscript 配置和初始化文件 ecosystem.config.js 进行了多环境运行的配置,我们可以根据需要进行切换环境。

package.json 文件添加如下:

"scripts": { "start": "node ./bin/www", "dev": "pm2 start ecosystem.config.js --env dev", "test": "pm2 start ecosystem.config.js --env test", "pro": "pm2 start ecosystem.config.js --env pro", "logs": "pm2 logs", "stop": "pm2 stop ecosystem.config.js" },

其中的

npm run start: 直接跑www文件,可用于调试
npm run dev: 开发环境
npm run test:测试环境
npm run pro:生产环境
npm run logs: 查看pm2的日志
npm run stop: 停止pm2服务

新增 ecosystem.config.js 文件:

module.exports = { apps : [{ name: 'API', script: './bin/www', // Options reference: pm2.io/doc/en/runtime/reference/ecosystem-file/ args: 'one two', instances: 1, autorestart: true, watch: true, ignore_watch: [ // 不用监听的文件 'node_modules', 'logs' ], max_memory_restart: '1G', env_pro: { "NODE_ENV": "production", "REMOTE_ADDR": "" }, env_dev: { "NODE_ENV": "development", "REMOTE_ADDR": "" }, env_test: { "NODE_ENV": "test", "REMOTE_ADDR": "" } }] };

这个文件主要是对pm2的基本配置,不用每次都进行配置,直接在文件进行改动即可。我们需要关注的是可以在 env 中,增加我们需要的环境及变量即可,文件中的 watch 属性是可以配置监听文件改动后,自动重启项目,比较好用。如果想忽略某一个文件夹的变动可以 ignore_watch ,更多的配置如果有兴趣的小伙伴可以查看官方文档的文档说明。

路由配置

该目录下存放路由基本配置,有 privatepublic 两个文件,引入路由后,我们对其前缀做了处理, router.prefix('/api') 在每一个请求的时候都需要带上这个前缀,抽出来也是为了服务目录的改变,可以直接更改即可,做了全局的操作。每一个路由都必须暴露出去,这样在app.js文件中使用该中间件。 publicRouter.allowedMethods() 根据 ctx.status 设置 response 响应头

// Routes app.use(publicRouter.routes(), publicRouter.allowedMethods()) app.use(privateRouter.routes(), privateRouter.allowedMethods())

private :该文件下的路由是需要通过jwt验证的,才能进行访问。前面我们做了jwt的中间件,我们直接引入即可 router.use(jwtMiddleware) 记得要放在请求路由的前面,才能保证每次都经过它。

'use strict' const Router = require('koa-router') const controllers = require('../controllers') const jwtMiddleware = require('../middlewares/jwt') const router = new Router() router.prefix('/api') router.use(jwtMiddleware) router.get('/test', controllers.test.test) module.exports = router

public :该文件与上面相反,主要用来不进行登录的校验,也就是我们常用的登录、注册等不需要验证的接口。

'use strict' const Router = require('koa-router') const controllers = require('../controllers') const router = new Router() router.prefix('/api') router.post('/login', controllers.login.login) module.exports = router

为什么我们没在这里处理业务逻辑呢?其实这里是遵循了MVC的思想,进行了分离。把数据库的操作放到了controllers文件中。这如果我们接口一多,不会显示得特别混乱。下面我们就来讲这个文件。

controllers文件

为了让整个项目更为模块化,该目录下主要是处理对应的路由的回调函数,一般我们不会在router文件中去操作数据库和逻辑操作等步骤,这里采用 routes 和 controller 分开,在方便代码的查看同时,也方便代码的维护和开发。

index.js文件:

该文件与models中的index.js文件中的集合该目录下的文件类似,这里是将其他文件导出统一到index暴露出去。

'use strict' const fs = require('fs') const files = fs.readdirSync(__dirname).filter(file => file !== 'index.js') const controllers = {} for (const file of files) { if (file.toLowerCase().endsWith('js')) { const controller = require(`./${file}`) controllers[`${file.replace(/\.js/, '')}`] = controller } } module.exports = controllers

其他文件的编写可以按照下面基本框架进行,在这里会用到前面封装好的业务,例如数据库操作、响应、jwt等操作。大家可以认真看以下代码分析一下。

'use strict' const jwt = require('jsonwebtoken') const config = require('../config') const User = require('../models/index').getModel('user') const login = {} login.login = async (ctx, next) => { const {userName, password} = ctx.request.body const user = await User.findOne({userName: userName}) if (!user) { ctx.result = '' ctx.msg = '用户不存在' } else { ctx.result = jwt.sign({ data: user._id, // 设置 token 过期时间 exp: Math.floor(Date.now() / 1000) + (60 * 60), // 60 seconds * 60 minutes = 1 hour }, config.secret) } return next() } module.exports = login

config.js文件

该文件主要用来存放全局的配置,如果一个项目中没有全局的配置,那么一个地方改动牵动的其他地方很多,这样很不利于工作效率,在开发过程中,我们一般会把常用的都放在这个文件,例如:数据库参数,端口,密钥,全局变量等。看自己的需求适当的更改。该文件将变量进行了暴露,引用时进行require即可。

'use strict' const path = require('path') module.exports = { port: '3001', secret: 'secret', publicDir: path.resolve(__dirname, './public'), logPath: path.resolve(__dirname, './logs/koa-template.log'), mongoDB: { database: 'mall', username: 'root', password: 'root', host: '127.0.0.1', port: 27017 } }

package.json文件

每个Nodejs项目的根目录下面,一般都会有一个package.json文件。该文件可以由npm init生成,定义了项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)。 package.json文件内部就是一个JSON对象,该对象的每一个成员就是当前项目的一项设置。我们也可在里面配置我们的 npm run XXX 的命令,大家可以根据需求进行配置。这是这项目需要用到的package.json文件。

{ "name": "koa-template", "version": "0.1.0", "author": "bayi", "private": true, "scripts": { "start": "node ./bin/www", "dev": "pm2 start ecosystem.config.js --env dev", "test": "pm2 start ecosystem.config.js --env test", "pro": "pm2 start ecosystem.config.js --env pro", "logs": "pm2 logs", "stop": "pm2 stop ecosystem.config.js" }, "dependencies": { "koa": "^2.6.2", "koa-bodyparser": "^4.2.1", "koa-helmet": "^4.1.0", "koa-jwt": "^3.5.1", "koa-router": "^7.4.0", "koa-static-cache": "^5.1.2", "koa2-cors": "^2.0.6", "log4js": "^3.0.6", "mongoose": "^5.5.5" } }

三、其他

####github地址:

github.com/bayi-lzp/koa-template (star! star!star!)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自由互联。

标签:方法步骤