内容简介:如果听了之后,对你有所启发和帮助,希望能帮忙转发一下。如果有问题,请关注下面公众号,发送问题给我。
戳蓝字「 Node全栈进阶 」关注我们哦!
编者注:作者是网易资深前端@金炳,当前负责网易严选自研Node框架建设工作。做过前端、后端、产品设计,是一名全栈工程师。目前致力于Node应用框架研究开发与生态建设,实践Node应用在Serverless、Faas场景下的迁移和落地,探索Service Mesh在Node应用中的价值。
Node的“字节码增强技术”你了解吗?纠正,专业名词叫monkey patch
一、介绍
1.1 什么是“字节码加强技术”?
有些人可能没有听过“字节码增强技术”是什么?
这个技术其实来源于Java,被一些牛逼的 Java 工程师掌握的核心技术之一,被用来开发一些底层的基建类 工具 或者平台使用。
“字节码增强技术”: 在Java字节码生成之后, 运行期 对其进行修改,增强其功能,这种方式相当于对应用程序的二进制文件进行修改。Java字节码增强主要用来提供一些现有代码没有的功能,赋能原有项目,或者增加性能等。
1.2 类比Node
概括的讲:相当于我们用typescript或者javascript写的代码,编译成一个js文件或者打包后,使用了“字节码增强技术”之后,可以增强原有的代码或者修改底层的代码。例如原来写了一个node程序,通过加入这个技术之后,你可以将原有的node程序对接到分布式链路跟踪平台上,看到对应的链路情况,代码并没有改,但是你让一个简单的node项目有了链路跟踪的功能。那我把它也叫做Node的“字节码增强技术”了。
二、举个简单的例子
2.1 写个程序
我们为了文章的可读性,贴太多代码不好,所以举一个特别简单的代码:首先我们创建一个工程
// 创建一个工程目录 mkdir test_code // 进入工程目录 cd test_code // 初始化package.json npm init -y // 安装koa的依赖 npm install koa -s
然后我们创建一个index.js
var koa = require('koa') const app = new koa(); app.use((ctx, next)=>{ ctx.body = "hello world"; }) app.listen(8000);
然后我们运行这个工程:
node index.js
然后我们就可以访问http://127.0.0.1:8000,然后就能在浏览器上看到"hello world"了。
2.2 使用“字节码增强技术”
假设上面的代码,就是我们的业务代码。
我们做基建的人,肯定最好的情况就是不去修改上面的代码。所以我们就来利用“字节码增强技术”来开发一个工具,来增强原来的代码。
我们这个工具名字:power.js
利用“字节码增强技术”,我们需要借助shimmer这个npm包(早先知道他的时候,下载还很少,现在越来越多人用了)。如下:每周下载量有105万了,说明项目底层可能都用了,大家放心使用。
我们安装一下shimmer这个依赖
npm install shimmer -S
然后power.js的代码如下:
我们比如想要增强,原先代码,我们不知道有哪些path被调用了,那我们就增强一下这个功能。
var shimmer = require('shimmer'); var http = require('http'); // 此处为了简单,http.createServer(handler) shimmer.wrap(http, "createServer", function wrapCreateServer(original){ return function wrapFunction (handler){ let newFunction = function(req, res){ console.log(req.url); return handler(req, res); } return original.call(this, newFunction); } });
上面为了简单演示,就是我们会去加强原有http模块的createServer函数,作用就是将原有的handler做一个wrap。
相当于我们不管用koa还是express,我们底层都会去调用http.createServer方法。
所以我们通过加强http.createServer的handler方法。
然后我们怎么在应用:
node -r power.js index.js
我们通过-r power.js去引入这个文件
然后我们打开浏览器http://127.0.0.1:8000/hello,然后我们能看到,命令行里面会打印了
/hello
相当于打印出了这个url。
所以我们并没有去修改原有代码,而且这个插件,我们再使用一个express的应用程序,这个我体现在这个通用性这章节
2.3 通用性特点
为了验证这个通用性,我们在写一个express程序,
var express = require('express'); var app = express(); app.get('/*', function (req, res) { res.send('Hello World!'); }); app.listen(3000);
然后我们也这个运行:
node -r power.js index.js
然后我们打开浏览器http://127.0.0.1:8000/hello,然后我们能看到,命令行里面会打印了
/hello
相当于打印出了这个url。
2.4 总结
当我们组的一些开发开发了一个应用,然后我们通过“字节码增强技术”开发了一个插件,然后让组内其他成员,运行应用的时候,去-r ./xxx,就能增强原来的代码了,比如有没有内存泄漏呀,链路跟踪,每次请求的返回啊,都能去做统计。
三、应用场景
3.1 基建类
上面这个我们举例了一个应用场景,比如其他成员开发了一个node业务项目,然后基建成员,可以去开发一个插件,让业务方成员启动的时候,加上这个参数。
最终实现:
-
内存泄漏统计
-
链路跟踪
-
每个请求的返回的耗时
-
错误捕获的上报
-
mysql的调用情况的一些统计
-
等等
3.2 业务项目中的应用
上面我们演示的是node程序,他其实也能应用在前端代码中。
比如我们使用基建代码的时候,发现这个基建在某种情况下出问题了,这个时候我们就可以去做这个wrap操作。
否则等组件发包比较慢,这个时候,我们通过wrap原来的original函数,然后最终修复这个基建中出现的问题。
四、建议
上面的代码中演示的代码比较简陋,只是为了让大家能更好的理解。
4.1 插件包建议用typescript
因为我们wrap的时候,需要去看原有函数,而且原有函数可能有多种参数情况,所以我们typescript的时候,我们就能更好的看到这个情况。防止少覆盖了一些情况。
4.2 参考一些现有代码和官方文档
另外大家可以查看pandora.js这个项目里面这个的使用方式,以及另外github上面去搜索这个代码片段,就能看到一些基础类的代码中,都用了这个shimmer。
五、原理
像react、angular等,我们其实分析到底下,他最后就会落到那么几个最底层的原理。
那我们打开shimmer包。
打开源码地址:
https://github.com/othiym23/shimmer/blob/master/index.js
就一个文件,大家看一下就能看完了,最终这个包的最底层就是:
Object.defineProperty
如果听了之后,对你有所启发和帮助,希望能帮忙转发一下。如果有问题,请关注下面公众号,发送问题给我。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
One Click
Richard L. Brandt / Portfolio Hardcover / 2011-10-27 / 25.95
An insightful look at how Amazon really works and how its founder and CEO makes it happen. Amazon's business model is deceptively simple: make online shopping so easy and convenient that customers ......一起来看看 《One Click》 这本书的介绍吧!