node koa2 ssr项目搭建的方法步骤


Posted in Javascript onDecember 11, 2020

一、创键项目

1.创建目录 koa2

2.npm init 创建 package.json,然后执行 npm install

3.通过 npm install koa 安装 koa 模块

4.通过 npm install supervisor 安装supervisor模块, 用于node热启动

5.在根目录下中新建 index.js 文件,作为入口文件, 内容如下:

const Koa = require('koa'); // Koa 为一个class
const app = new Koa();
 
app.use(async (ctx, next) => {
 await next();
 ctx.response.body = 'Hello, koa2!';
});
 
app.listen(9527, () => {
 console.log('This server is running at http://localhost:' + 9527)
})

6.配置package

{
 "name": "koa",
 "version": "1.0.0",
 "description": "",
 "main": "koa.js",
 "scripts": {
 "serve": "supervisor koa.js"
 },
 "author": "",
 "license": "ISC",
 "dependencies": {
 "koa": "^2.7.0",
 "supervisor": "^0.12.0"
 }
}

7 . 启动

npm run serve

二、路由配置

cnpm i koa-router
const router = new Router(); // 实例化路由

router.get('/', async (ctx, next) => {
 ctx.response.body = '<h5>好家伙</h5>';
});
app.use(router.routes());

路由参数

//请求地址 www.*****/sss?from=1

router.get('/hello/:name', async (ctx, next) => {
 var name = ctx.params.name; // 获取请求参数 sss
 var from = ctx.query.from; // 1
 ctx.response.body = `<h5>好家伙, ${name}!</h5>`;
});

三、请求

post

const bodyParser = require('koa-bodyparser');
 app.use(bodyParser());


router.post('/login', async (ctx, next) => {
 let name = ctx.request.body.name;
 let password = ctx.request.body.password;
 console.log(name, password);
 ctx.response.body = `<h4>好家伙, ${name}!</h4>`;
});

get

router.get('/', async (ctx, next) => {
 ctx.response.body = '<h4>好家伙</h4>'
});

四、html模板

1、好处

使用html模板,将html从js中分离出去,有助于项目开发和管理。而且,html模板在koa2中,必须通过中间件来实现。

2、koa-views + nunjucks实现html模板

nunjucks.configure(resolve(__dirname, 'views'), { autoescape: true });

 app.use(views(__dirname + '/views', {
 map: { html: 'nunjucks' }
 }));

五、操作静态资源

1、静态资源在开发中的地位

静态资源环境在服务端是十分常用的一种服务,在后台开发中不仅有需要代码处理的业务逻辑请求,也会有很多的静态资源请求。比如请求js,css,jpg,png这些静态资源请求。也非常的多,有些时候还会访问静态资源路径。

2、koa-static-cache实现静态资源操作

app.use(
 staticCache(resolve("dist"), {
  maxAge: 365 * 24 * 60 * 60
 })
)

六、进阶

1、结构

node koa2 ssr项目搭建的方法步骤

入口文件(index.js)

const Koa = require('koa')
const bodyParser = require('koa-bodyparser');
const staticCache = require('koa-static-cache');
const views = require('koa-views')
const {resolve} = require('path')
const R = require('ramda')
const MIDDLEWARES = ['router'] //中间件配置文件
const nunjucks = require('nunjucks')
const logsUtil = require('../utils/logs.js');

//中间件导入 路由导入
const useMiddlewares = (app) => {
 R.map(
 R.compose(
  R.forEachObjIndexed(
  initWith => initWith(app)
  ),
  require,
  name => resolve(__dirname, `./middlewares/${name}`)
 )
 )(MIDDLEWARES)
}

;(async () => {
 const app = new Koa();
 // view engine setup
 nunjucks.configure(resolve(__dirname, 'views'), { autoescape: true });
 //views with nunjucks
 app.use(views(__dirname + '/views', {
  map: { html: 'nunjucks' }
 }));
 app.use(bodyParser());
 app.use(logsUtil.accessInfo()); //访问日志

 //静态资源配置缓存
 app.use(
   staticCache(resolve("dist"), {
    maxAge: 365 * 24 * 60 * 60
  })
 )
 
 app.on('error', err => {
 
 });

 app.use(async (ctx,next) => {
   await next()
  if(parseInt(ctx.status) === 404){
  ctx.response.redirect("/404")
 }
 
 });
  await useMiddlewares(app) //导入中间件

  app.listen(9527,() => {
 console.log('Server running on port %d', 9527);
 })
})()

2、路由中间件封装

   1.新建middlewares文件夹   在下面新建router.js
   2.新建lib文件夹 在下面新建decorator.js
   3.新建routes下面新建views.js

router.js

const { Route } = require('../lib/decorator')
const { resolve } = require('path')

export const router = app => {
 const apiPath = resolve(__dirname, '../routes')
 const router = new Route(app, apiPath);
 router.init()
}

decorator.js

const Router = require('koa-router')
const { resolve } = require('path')
const _ = require('lodash')
const glob = require('glob')
const R = require('ramda')

const symbolPrefix = Symbol('prefix')
const routerMap = new Map()

const isArray = c => _.isArray(c) ? c : [c]

export class Route {
 constructor (app, apiPath) {
 this.app = app
 this.apiPath = apiPath
 this.router = new Router()
 }

 init () {
 glob.sync(resolve(this.apiPath, './**/*.js')).forEach(require)
 for (let [conf, controller] of routerMap) {
  const controllers = isArray(controller)
  let prefixPath = conf.target[symbolPrefix]
  if (prefixPath) prefixPath = normalizePath(prefixPath)
  const routerPath = prefixPath + conf.path
  this.router[conf.method](routerPath, ...controllers)
 }

 this.app.use(this.router.routes())
 this.app.use(this.router.allowedMethods())
 }
}

const normalizePath = path => path.startsWith('/') ? path : `/${path}`

const router = conf => (target, key, descriptor) => {
 conf.path = normalizePath(conf.path)
 routerMap.set({
 target: target,
 ...conf
 }, target[key])
}

export const controller = path => target => (target.prototype[symbolPrefix] = path)

export const get = path => router({
 method: 'get',
 path: path
})

export const post = path => router({
 method: 'post',
 path: path
})

export const put = path => router({
 method: 'put',
 path: path
})

export const del = path => router({
 method: 'delete',
 path: path
})

export const use = path => router({
 method: 'use',
 path: path
})

export const all = path => router({
 method: 'all',
 path: path
})

view.js

const { controller, get } = require('../lib/decorator')
@controller('')
export class viewController {
 @get('/')
 async home(ctx, next) { 
 await ctx.render('index', {
 
 })
 }
 
 @get('/service')
 async enter(ctx, next) {
 await ctx.render('service', {
 title: '',
 })
 }
 
 @get('/404')
 async pageNUll(ctx, next) {
 await ctx.render('404', {
 title: ' ',
 })
 }
}

3、日志文件

cnpm i koa-log4

config/logs.jsvar path = require('path');

//日志根目录
var baseLogPath = path.resolve(__dirname, '../logs')

/*报错输出日志*/
//错误日志目录、文件名、输出完整路径
var errorPath = "/error";
var errorFileName = "error";
var errorLogPath = baseLogPath + errorPath + "/" + errorFileName;

/*请求数据得到响应时输出响应日志*/
//响应日志目录、文件名、输出完整路径
var responsePath = "/response";
var responseFileName = "response";
var responseLogPath = baseLogPath + responsePath + "/" + responseFileName;

/*操作数据库进行增删改等敏感操作记录日志*/
//操作日志目录、文件名、输出完整路径
var handlePath = "/handle";
var handleFileName = "handle";
var handleLogPath = baseLogPath + handlePath + "/" + handleFileName;

/*访问级别日志*/
var accessPath = "/access"
var accessFileName = "access";
var accessLogPath = baseLogPath + accessPath + "/" + accessFileName;

/*访问级别日志*/
var reqPath = "/req"
var reqFileName = "req";
var reqLogPath = baseLogPath + reqPath + "/" + reqFileName;

module.exports = {
 //日志格式等设置
 appenders:
  {
   "rule-console": {"type": "console"},
   "errorLogger": {
    "type": "dateFile",
    "filename": errorLogPath,
    "pattern": "-yyyy-MM-dd.log",
    "alwaysIncludePattern": true,
    "encoding": "utf-8",
    "path": errorPath
   },
   "resLogger": {
    "type": "dateFile",
    "filename": responseLogPath,
    "pattern": "-yyyy-MM-dd.log",
    "alwaysIncludePattern": true,
    "encoding": "utf-8",
//    "maxLogSize": 204800,
//    "numBackups": 3,
    "path": responsePath
   },
   "handleLogger": {
    "type": "dateFile",
    "filename": handleLogPath,//生成文件路径和文件名
    "pattern": "-yyyy-MM-dd.log",
    "alwaysIncludePattern": true,
    "encoding": "utf-8",
//    "maxLogSize": 204800,
//    "numBackups": 3,
    "path": handlePath
   },
   "accessLogger": {
    "type": "dateFile",
    "filename": accessLogPath,
    "pattern": "-yyyy-MM-dd.log",
    "alwaysIncludePattern": true,
    "encoding": "utf-8",
//    "maxLogSize": 204800,
//    "numBackups": 3,
    "path": accessPath
   },
   "reqLogger": {
    "type": "dateFile",
    "filename": reqLogPath,
    "pattern": "-yyyy-MM-dd.log",
    "alwaysIncludePattern": true,
    "encoding": "utf-8",
//    "maxLogSize": 204800,
//    "numBackups": 3,
    "path": reqPath
   },
  },
 //供外部调用的名称和对应设置定义
 categories: {
  "default": {"appenders": ["rule-console"], "level": "all"},
  "resLogger": {"appenders": ["resLogger"], "level": "info"},
  "errorLogger": {"appenders": ["errorLogger"], "level": "error"},
  "handleLogger": {"appenders": ["handleLogger"], "level": "all"},
  "accessLogger": {"appenders": ["accessLogger"], "level": "all"},
  "reqLogger": {"appenders": ["reqLogger"], "level": "error"}
 },
 "baseLogPath": baseLogPath
}

log.js

var log4js = require('koa-log4');
var logsConfig = require('../config/logs.js');
//加载配置文件
log4js.configure(logsConfig);
//调用预先定义的日志名称
var resLogger = log4js.getLogger("resLogger");
var errorLogger = log4js.getLogger("errorLogger");
var handleLogger = log4js.getLogger("handleLogger");
var reqLogger = log4js.getLogger("reqLogger");
var consoleLogger = log4js.getLogger();

exports.accessInfo = () => log4js.koaLogger(log4js.getLogger('accessLogger'));//访问日志
exports.logInfo = (data) => {consoleLogger.info(data)}
.............
.............

关于pm2自动部署   webpack打包  以及数据库后续有时间更新

欢迎干饭人一起推动优化

最后附上工具人地址:https://gitee.com/angry2bird/node-koa

到此这篇关于node koa2 ssr项目搭建的方法步骤的文章就介绍到这了,更多相关node koa2 ssr项目搭建内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
JqGrid web打印实现代码
May 31 Javascript
浅析Js(Jquery)中,字符串与JSON格式互相转换的示例(直接运行实例)
Jul 09 Javascript
深入理解Javascript中的循环优化
Nov 09 Javascript
js几秒以后倒计时跳转示例
Dec 26 Javascript
JavaScript整除运算函数ceil和floor的区别分析
Apr 14 Javascript
跟我学习javascript的undefined与null
Nov 17 Javascript
js点击按钮实现带遮罩层的弹出视频效果
Dec 19 Javascript
jquery easyUI中ajax异步校验用户名
Aug 19 Javascript
js实现碰撞检测特效代码分享
Oct 16 Javascript
Bootstrap CSS布局之表格
Dec 17 Javascript
详解react-router4 异步加载路由两种方法
Sep 12 Javascript
vue基本使用--refs获取组件或元素的实例
Nov 07 Javascript
uni-app 自定义底部导航栏的实现
Dec 11 #Javascript
微信小程序实现音乐播放页面布局
Dec 11 #Javascript
JS实现可以用键盘方向键控制的动画
Dec 11 #Javascript
JS实现京东商品分类侧边栏
Dec 11 #Javascript
vue使用exif获取图片经纬度的示例代码
Dec 11 #Vue.js
vue使用exif获取图片旋转,压缩的示例代码
Dec 11 #Vue.js
一行JavaScript代码如何实现瀑布流布局
Dec 11 #Javascript
You might like
一道求$b相对于$a的相对路径的php代码
2010/08/08 PHP
浅谈php优化需要注意的地方
2014/11/27 PHP
用PHP生成excel文件到指定目录
2015/06/22 PHP
浅谈PHP中类和对象的相关函数
2017/04/26 PHP
PHP封装curl的调用接口及常用函数详解
2018/05/31 PHP
PHP实现数组向任意位置插入,删除,替换数据操作示例
2019/04/05 PHP
Nigma vs AM BO3 第二场2.13
2021/03/10 DOTA
js实现的真正的iframe高度自适应(兼容IE,FF,Opera)
2010/03/07 Javascript
js实现双向链表互联网机顶盒实战应用实现
2011/10/28 Javascript
jquery animate实现鼠标放上去显示离开隐藏效果
2013/07/21 Javascript
采用自执行的匿名函数解决for循环使用闭包的问题
2014/09/11 Javascript
显示今天的日期js代码(阳历和农历)
2014/09/30 Javascript
AngularJS 执行流程详细介绍
2016/08/18 Javascript
JQuery和html+css实现带小圆点和左右按钮的轮播图实例
2017/07/22 jQuery
详解node+express+ejs+bootstrap构建项目
2017/09/27 Javascript
jquery鼠标悬停导航下划线滑出效果
2017/09/29 jQuery
微信小程序实现刷脸登录
2018/05/25 Javascript
jQuery动态生成的元素绑定事件操作实例分析
2019/05/04 jQuery
让 babel webpack vue 配置文件支持智能提示的方法
2019/06/22 Javascript
微信小程序之几种常见的弹框提示信息实现详解
2019/07/11 Javascript
Node.js API详解之 dns模块用法实例分析
2020/05/15 Javascript
[05:04]DOTA2上海特级锦标赛主赛事第二日TOP10
2016/03/04 DOTA
python实现在控制台输入密码不显示的方法
2015/07/02 Python
python脚本设置系统时间的两种方法
2016/02/21 Python
神经网络python源码分享
2017/12/15 Python
python SVM 线性分类模型的实现
2019/07/19 Python
tensorflow 限制显存大小的实现
2020/02/03 Python
Python 抓取数据存储到Redis中的操作
2020/07/16 Python
pyqt5 textEdit、lineEdit操作的示例代码
2020/08/12 Python
某科技软件测试面试题
2013/05/19 面试题
幼儿园中班上学期评语
2014/04/18 职场文书
物流专业专科生职业生涯规划书
2014/09/14 职场文书
综合测评个人总结
2015/03/03 职场文书
环卫工作个人总结
2015/03/04 职场文书
高中生个性发展自我评价
2015/03/09 职场文书
golang 实现对Map进行键值自定义排序
2021/04/28 Golang