Vue服务端渲染Bigpipe,IO密集Koa 2等问题回复
Posted Node全栈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue服务端渲染Bigpipe,IO密集Koa 2等问题回复相关的知识,希望对你有一定的参考价值。
狼叔说:最近因为工作,以及家里生娃,没太多更新,请大家谅解,只要我时间ok就会尽量更新的~
整理了一下最近大家问的比较多的问题,具体如下,希望对大家有用
为啥说Node.js适合io密集操作
理解http,基本的请求响应模型
var http = require("http");
http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/plain" }); res.write("Hello World"); res.end();
}).listen(8888);
理解事件驱动,凡是简单on("data",function(chunk){}
的,是listener监听器,都是继承自EventEmit才有的功能,那么事件emit发射在哪里?自己试着想想
var http = require('http');
http.createServer(function(request, response) { var body = []; request.on('data', function(chunk) { body.push(chunk); }).on('end', function() { body = Buffer.concat(body).toString(); response.end(body); });
}).listen(8080);
理解Stream,各种语言、框架里pipe管道(比如shell里,比如gulp里的pipe),本身http就是io操作比较多,使用Stream流式处理可以减少切换成本,无中间文件等,
Stream学习资料 https://cnodejs.org/topic/570b1fa494b38dcb3c09a7f8
var http = require('http');
http.createServer(function(request, response) { if (request.method === 'GET' && request.url === '/echo') { request.pipe(response); } else { response.statusCode = 404; response.end(); }
}).listen(8080);
如果一个请求要多次处理呢?
request.pipe(xx).pipe(yy).pipe(response);
总结,说Node.js适合io密集操作,确实是,就是为了Node.js异步io而生的。这部分是有优化的,所以它比较强,如果在cpu密集方面也有类似的库,是不是它也适合cup密集工作呢?凡事皆有二面性,非不能解,看想不想解。
koa好是好,不过第三方生态圈不如express,express好多比较有特色的模块,并不直接支持koa
koa好是好,不过第三方生态圈不如express,express好多比较有特色的模块,并不直接支持koa。虽然也可以转,但是用起来还是不如原生用的方便。
如果说要比生态,用java和php等老牌语言会更加成熟。其实选型取舍是需求和追求,express已经很长时间了,是非常稳定的web框架。从代码提交、issues、测试就可以看出来。明显比Koa要完善很多。本质上,它最多是Node.js http模块的强力补充。
我们又要回到那个很久远的问题,都喜欢温水,都不喜欢冷水,换一个环境多少会有不适应的感觉。最好是一只不变下去。但实际呢?技术的驱动和演进往往是那些打破你舒适区的东西。我也是个express老司机,我也很喜欢拿express去理解koa,被苏大fengmk2喷过好几次,如果要完全一样,革新干什么呢?
举个例子:webpack-dev-middleware算比较火热的模块了,它只支持express
如果想改写成Koa版本,你需要掌握2点
Koa中间件写法(基础)
webpack-dev-middleware模块的用法
代码如下
'use strict'
const devMiddleware = require('webpack-dev-middleware')
module.exports = (compiler, opts) => { const expressMiddleware = devMiddleware(compiler, opts) return (ctx, next) => { return expressMiddleware(ctx.req, { end: (content) => { ctx.body = content
}, setHeader: (name, value) => { ctx.headers[name] = value
} }, next); }
}
用法,传参都一样
return (ctx, next) => {} 是Koa 2.x经典的中间件写法
配置项end和setHeader等都是webpack-dev-middleware里需要的
就这点代码,难度很大么?折腾了一番,相信大家对webpack-dev-middleware这个模块会有更深入的理解。
爷爷都是从孙子走过来的,哪个大牛没写过hello world!
Koa-bigpipe
bigpipe当年给facebook立了很大功劳。给出百科简介
BigPipe是一个重新设计的基础动态网页服务体系。大体思路是,分解网页成叫做Pagelets的小块,然后通过Web服务器和浏览器建立管道并管理他们在不同阶段的运行。这是类似于大多数现代微处理器的流水线执行过程:多重指令管线通过不同的处理器执行单元,以达到性能的最佳。虽然BigPipe是对现有的服务网络基础过程的重新设计,但它却不需要改变现有的网络浏览器或服务器,它完全使用PHP和javascript来实现。
它只是优化技术而已,很明显这段简介里是有问题的。早起fb是php,微博也是php,所以才有这个无解。但技术问题是通用的,所有语言都可以实现,只是看哪个简单哪个高效而已。用Node.js实现bigpipe是非常好的选择。
这里简单说一下大家对bigpipe技术的感觉,在express使用res.write,多次写html片段到浏览器,而已。
原理上确实是这样的,所以说也对也不对,原因是你真的在项目里使用它了么?
Koa里没有提供对bigpipe的支持,ctx.body赋值做了很多约定。可以说是不太容易控制。
http模块是基于stream的,所以方案1是通过require(‘stream’).Readable来处理,这种是非常容易理解,但要求大家对stream有一个比较好的理解。
方案2,反正Koa和express都是基于http模块的,那么为什么不用http模块的方法呢?
在Koa里有2个概念非常容易混,req和request,res和response,我们经常在express里用req和res,但在Koa里它们指的是http启动server时传入的req和res参数
var http = require("http");http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/plain" }); res.write("Hello World"); res.end();
}).listen(8888);
那么是不是可以不用Koa的东西,改用http的接口呢?res.write和express里的res.write是一样的。
所以代码如下
'use strict'
/** * Module exports. * @public */
module.exports = (ctx, next) => { ctx.type = 'html' ctx.status= 200 ctx.chunks = [] let req = ctx.req let res = ctx.res // write chunk to browser ctx.write = (chunk) => { if (!chunk) { return ctx.end() } ctx.chunks.push(chunk) res.write(chunk) } // end response ctx.end = (chunk) => { if (chunk) { ctx.write(chunk) } res.end(null) } return next()
}
总结一下,ctx.write和ctx.end方法是为了保持跟koa风格一致,ctx本身是上下文的意思,通过提供这2个方法来完成bigpipe,其实如果从简,你直接ctx.res.write也是可以的。
vue ssr
抓出一段代码
// example usage with express
app.get('/', (req, res) => { const vm = new App({ url: req.url }) const stream = renderer.renderToStream(vm) res.write(`<!DOCTYPE html><html><head><title>...</title></head><body>`) stream.on('data', chunk => { res.write(chunk) }) stream.on('end', () => { res.end('</body></html>') })
})
这很明显就是express里bigpipe的写法。如果你想把它改成Koa版本的,那么你首先要搞定Koa版本的bigpipe如何实现。然后再考虑vue的ssr。
如果盲点太多,又怕坑,那么还是早早的转行吧,这个时刻需要学习的行业不适合你~
退一步讲,如果连express这段代码都不是特别懂,那还是乖乖的用express好了。
给出Koa vue ssr的代码
app.use((ctx, next) => { let res = ctx.res let req = ctx.req if (!renderer) { return res.end('waiting for compilation... refresh in a moment.') } var s = Date.now() const context = { url: req.url } const renderStream = renderer.renderToStream(context) let firstChunk = true ctx.write(html.head) renderStream.on('data', chunk => { if (firstChunk) { // embed initial store state if (context.initialState) { ctx.write( `<script>window.__INITIAL_STATE__=${ serialize(context.initialState, { isJSON: true }) }</script>` ) } firstChunk = false } ctx.write(chunk) }) renderStream.on('end', () => { ctx.end(html.tail) console.log(`whole request: ${Date.now() - s}ms`) }) renderStream.on('error', err => { throw err
})
})
使用了ES6和module,如何做测试和覆盖率
测试和覆盖问题
这个问题有点蒙,测试框架是独立的,通用的,对Koa还是express没有啥区别。
引入es6对测试的影响,我觉得只是多了一步实例化的过程,整体并无太多。另外其他特性,新版的测试框架都已经集成的差不多了。
如果激进点,选择ava,非常爽,非常快,尤其是新特性,如果想保守点,可以用mocha,另外jest和jasmine也不错。
测试覆盖率还是要在根上看,如果严格遵守tdd或bdd,做这个比较容易。如果是为了做而做就失去意义的。
Google出来的文章分不清Koa 1和Koa 2
不能一概而论,下面的方法可以快速辨别
方法1
直接用的是Koa1
var koa = require('koa')var app = koa()
实例化的是Koa2
const Koa = require('koa')const app = new Koa()
方法2
中间件,完全是generator的,一定是koa1
function* hello() { yield 'hello'; yield function () { return 'generator'; }; return 'done';
}
如果出现convert和co.wrap的就是Koa2
另外async/await和function(ctx, next)也是koa2
方法3
在处理过程中,大量使用this的,是koa1
而使用ctx显示声明的,是koa2
我使用了koa static管理public资源,当资源不存在时,依然走了后面的N个中间件,怎么才能在资源没有时,直接404
这其实是中间件的原理问题。
static放到最前面,如果找不到资源,自然会将请求转交给后面的路由或中间件的的。
可以使用 https://github.com/koa-modules/serve-static 这个,效率高,逻辑等同express。
至于中间件原理,限于篇幅,参见 https://github.com/i5ting/stuq-koa
大前端和 Node.js那些事儿
文中很多内容讲的不够深入,如果想交流,请在1月24日知乎live上详聊,我要讲的主题是《大前端和Node.js哪些事儿》有兴趣的可以来聊聊
本次 Live 是受斯达克学院「 StuQ 公开课」的邀请,并与「 StuQ 公开课」共同策划,我将围绕大前端和 Node.js 进行深度解读。随着大前端的演进与火爆, h5 、 hybrid 、组简化、小程序,越来越多的公司和程序员不得不去重视前端,那么多框架 react 、 vue 、 ng2 到底该怎么选?没有很多经验的程序员该如何高效的解决问题?对于不得不用的 Node.js 欲拒还迎,到底该如何抉择?作为资深全栈工程师、架构师、实践者,狼叔带你回顾 2016 ,展望 2017 ,以 Node.js 视角来帮助大家更好处理前端问题。
本次 Live 主要包括以下内容:
* Node.js 2016 回顾
* Node.js 的应用场景(前端工具、 proxy2 种、后端、微服务)
* Node.js 如何高效配合服务器端渲染(以 react 、 vue 为例)
* 如何结合 Node.js 完成更多(以最近写的 bigview 模块为例)
* 如何在真实项目里使用、推广 Node.js ?
* Node.js 2017 展望
如果想参与Live一起来聊聊,请点击阅读原文链接,进入知乎Live链接
全文完
你身边如果有朋友对Node.js或全栈感兴趣,可以转发给他们看看哦,O(∩_∩)O先谢过
以上是关于Vue服务端渲染Bigpipe,IO密集Koa 2等问题回复的主要内容,如果未能解决你的问题,请参考以下文章
Vue+koa2开发一款全栈小程序(5.服务端环境搭建和项目初始化)
前后端分离全栈开发项目师徒开启,VUE+koa+MongoDB!