node koa2 ssr項目搭建的方法步驟
一、創(chuàng)鍵項目
1.創(chuàng)建目錄 koa2
2.npm init 創(chuàng)建 package.json,然后執(zhí)行 npm install
3.通過 npm install koa 安裝 koa 模塊
4.通過 npm install supervisor 安裝supervisor模塊, 用于node熱啟動
5.在根目錄下中新建 index.js 文件,作為入口文件, 內(nèi)容如下:
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());
路由參數(shù)
//請求地址 www.*****/sss?from=1
router.get('/hello/:name', async (ctx, next) => {
var name = ctx.params.name; // 獲取請求參數(shù) 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中分離出去,有助于項目開發(fā)和管理。而且,html模板在koa2中,必須通過中間件來實現(xiàn)。
2、koa-views + nunjucks實現(xiàn)html模板
nunjucks.configure(resolve(__dirname, 'views'), { autoescape: true });
app.use(views(__dirname + '/views', {
map: { html: 'nunjucks' }
}));
五、操作靜態(tài)資源
1、靜態(tài)資源在開發(fā)中的地位
靜態(tài)資源環(huán)境在服務(wù)端是十分常用的一種服務(wù),在后臺開發(fā)中不僅有需要代碼處理的業(yè)務(wù)邏輯請求,也會有很多的靜態(tài)資源請求。比如請求js,css,jpg,png這些靜態(tài)資源請求。也非常的多,有些時候還會訪問靜態(tài)資源路徑。
2、koa-static-cache實現(xiàn)靜態(tài)資源操作
app.use(
staticCache(resolve("dist"), {
maxAge: 365 * 24 * 60 * 60
})
)
六、進階
1、結(jié)構(gòu)

入口文件(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');
//中間件導(dǎo)入 路由導(dǎo)入
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()); //訪問日志
//靜態(tài)資源配置緩存
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) //導(dǎo)入中間件
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;
/*請求數(shù)據(jù)得到響應(yīng)時輸出響應(yīng)日志*/
//響應(yīng)日志目錄、文件名、輸出完整路徑
var responsePath = "/response";
var responseFileName = "response";
var responseLogPath = baseLogPath + responsePath + "/" + responseFileName;
/*操作數(shù)據(jù)庫進行增刪改等敏感操作記錄日志*/
//操作日志目錄、文件名、輸出完整路徑
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 = {
//日志格式等設(shè)置
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
},
},
//供外部調(diào)用的名稱和對應(yīng)設(shè)置定義
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);
//調(diào)用預(yù)先定義的日志名稱
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)}
.............
.............
關(guān)于pm2自動部署 webpack打包 以及數(shù)據(jù)庫后續(xù)有時間更新
歡迎干飯人一起推動優(yōu)化
最后附上工具人地址:https://gitee.com/angry2bird/node-koa
到此這篇關(guān)于node koa2 ssr項目搭建的方法步驟的文章就介紹到這了,更多相關(guān)node koa2 ssr項目搭建內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Node.js API詳解之 string_decoder用法實例分析
這篇文章主要介紹了Node.js API詳解之 string_decoder用法,結(jié)合實例形式分析了Node.js API中string_decoder的功能、用法及操作注意事項,需要的朋友可以參考下2020-04-04
輕松創(chuàng)建nodejs服務(wù)器(2):nodejs服務(wù)器的構(gòu)成分析
這篇文章主要介紹了輕松創(chuàng)建nodejs服務(wù)器(2):nodejs服務(wù)器的構(gòu)成分析,本文是對第一節(jié)中簡單服務(wù)器的代碼進行分析總結(jié),需要的朋友可以參考下2014-12-12
解決node.js含有%百分號時發(fā)送get請求時瀏覽器地址自動編碼的問題
這篇文章主要介紹了解決node.js含有%百分號時發(fā)送get請求時瀏覽器地址自動編碼的問題,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-11-11
nodejs版本過高導(dǎo)致vue2版本的項目無法正常啟動的解決方案
這篇文章主要給大家介紹了關(guān)于nodejs版本過高導(dǎo)致vue2版本的項目無法正常啟動的解決方案,本文小編給大家詳細(xì)介紹了如何解決這個問題,如有遇到同樣問題的朋友可以參考下2023-11-11
nodejs+axios爬取html出現(xiàn)中文亂碼并解決示例
這篇文章主要為大家介紹了nodejs+axios爬取html出現(xiàn)中文亂碼示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06
nodejs轉(zhuǎn)換音頻文件格式并壓縮導(dǎo)出zip格式(vscode語音插件開發(fā))
FFmpeg是一套開源的音視頻處理工具,通俗地講,可以對音視頻文件進行剪切、拼接、水印、轉(zhuǎn)碼等處理,這篇文章主要介紹了nodejs轉(zhuǎn)換音頻文件格式并壓縮導(dǎo)出zip格式(vscode語音插件開發(fā)),需要的朋友可以參考下2023-05-05

