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 相关文章推荐
jQuery 使用手册(三)
Sep 23 Javascript
node.js实现多图片上传实例
Jun 03 Javascript
通过location.replace禁止浏览器后退防止重复提交
Sep 04 Javascript
JavaScript基础语法、dom操作树及document对象
Dec 02 Javascript
15个常用的jquery代码片段
Dec 19 Javascript
node.js入门教程之querystring模块的使用方法
Feb 27 Javascript
详解Vuejs2.0 如何利用proxyTable实现跨域请求
Aug 03 Javascript
jquery在vue脚手架中的使用方式示例
Aug 29 jQuery
bootstrap table实现点击翻页功能 可记录上下页选中的行
Sep 28 Javascript
详解webpack 入门与解析
Apr 09 Javascript
Vue插件打包与发布的方法示例
Aug 20 Javascript
JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法详解【凹多边形的分离轴检测算法】
Dec 13 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
php中$_SERVER[PHP_SELF] 和 $_SERVER[SCRIPT_NAME]之间的区别
2009/09/05 PHP
如何在php中正确的使用json
2013/08/06 PHP
PHP防止post重复提交数据的简单例子
2014/06/07 PHP
PHP的拦截器实例分析
2014/11/03 PHP
PHP获取音频文件的相关信息
2015/06/22 PHP
php执行多个存储过程的方法【基于thinkPHP】
2016/11/08 PHP
js 页面输出值
2008/11/30 Javascript
document.getElementById方法在Firefox与IE中的区别
2010/05/18 Javascript
基于JavaScript实现继承机制之调用call()与apply()的方法详解
2013/05/07 Javascript
关于JS中的闭包浅谈
2013/08/23 Javascript
用javascript读取xml文件读取节点数据
2014/08/12 Javascript
JavaScript面对国际化编程时的一些建议
2015/06/24 Javascript
jQuery实现模仿微博下拉滚动条加载数据效果
2015/12/25 Javascript
基于javascript实现页面加载loading效果
2020/09/15 Javascript
js实现的下拉框二级联动效果
2016/04/30 Javascript
jquery解析XML及获取XML节点名称的实现代码
2016/05/18 Javascript
vue loadmore组件上拉加载更多功能示例代码
2017/07/19 Javascript
vux uploader 图片上传组件的安装使用方法
2018/05/15 Javascript
element-ui 的el-button组件中添加自定义颜色和图标的实现方法
2018/10/26 Javascript
vue中npm包全局安装和局部安装过程
2019/09/03 Javascript
JS通过识别id、value值对checkbox设置选中状态
2020/02/19 Javascript
解决echarts 一条柱状图显示两个值,类似进度条的问题
2020/07/20 Javascript
详解JavaScript中new操作符的解析和实现
2020/09/04 Javascript
[05:03]2018DOTA2亚洲邀请赛主赛事首日回顾
2018/04/04 DOTA
解决python flask中config配置管理的问题
2019/07/26 Python
Python字典深浅拷贝与循环方式方法详解
2020/02/09 Python
django 取消csrf限制的实例
2020/03/13 Python
Keras之fit_generator与train_on_batch用法
2020/06/17 Python
实习生单位鉴定意见
2013/12/04 职场文书
巾帼文明岗申报材料
2014/05/01 职场文书
会计工作总结范文2014
2014/12/23 职场文书
幼师自荐信范文
2015/03/06 职场文书
狼牙山五壮士观后感
2015/06/09 职场文书
一文读懂navicat for mysql基础知识
2021/05/31 MySQL
Python 内置函数速查表一览
2021/06/02 Python
HTML+CSS 实现顶部导航栏菜单制作
2021/06/03 HTML / CSS