Nodejs经验谈
前言
这里主要说一下之前使用Nodejs开发踩过的坑,只说坑不填坑,那就是赤裸地耍流氓,文中有大量的说明及填坑方法,了解的看官可以直接跳过。
PS:说实话,Nodejs的坑确实蛮多的;但是上手简单,扩展包众多,让你的开发变得十分简易。
1.代码精简
尽量使用精简的代码,Nodejs 代码处理速度是异常慢的,不如其他主流语言,甚至不如python,使用精简代码也是对自己能力的提升与考验。我们在做卡地亚商城项目时,对方工程师要求同一函数内,同一变量不可以出现三次(loop中仅算作一次)。代码精简了,就会变得漂亮,查找问题也变得容易,也方便后面的工程师接手处理。
不建议在Nodejs代码中再套用其他框架,例如coffeescript,Node与Coffee会报不同的错误。
2.精确版本号
这个坑,估计很多人都踩过,开发环境与实际环境不一致。同事开发一个模块,本地联调是没问题的,但是到server端后,根本无法启动,找了一圈,最后发现同事本地开发使用的是Node的化石版,就是这么个小疏忽,让我们浪费了一上午去找原因。
补充一些Node版本管理的知识:
* //任意版本
1.1.0 //指定版本
~1.1.0 //>=1.1.0 && < 1.2.0
^1.1.0 //>=1.1.0 && < 2.0.0
3.单元测试
一定要写单元测试用例,尝试本地运行,测试成功后再上传至服务器,有几次修改完代码(简单几行)以为怎么可能出问题,结果一重启服务就挂了,可能少个括号之类的。
Mocha是我最长使用的单元测试工具:
基本概念:
describe()测试区块,可以多层镶套。
it()测试用例,一个测试区块可以包含多个测试用例。
测试钩子:
before() 在本区块所有测试用例执行之前执行。
after() 在本区块所有测试用例执行之后执行。
beforeEach() 在本区块每个测试用例之前执行。
afterEach() 在本区块每个测试用例之后执行。
断言:
chai ;Mocha本身没断言,chai可以作为它的断言库。chai-as-promise 这个库支持promise。
用例管理:
only()测试区块与测试用例都支持only方法,只运行修饰的测试区块或用例。
skip()测试区块与测试用例都支持skip方法,会跳过修饰的测试区块或用例。
only与skip共用时,only会忽略掉skip。
异步调用:
done(),测试方法异步完成后,被调用。一个it测试实例中只能有一个done()。
例:
var assert = require('chai').assert; function add() {
return Array.prototype.slice.call(arguments).reduce(function (prev, curr) {
return prev + curr;
}, 0);
} describe('add()', function () {
var tests = [
{ args: [1, 2], expected: 3 },
{ args: [1, 2, 3], expected: 6 }
]; tests.forEach(function (test) {
it('test adds ' + test.args.length + ' args', function () {
var res = add.apply(null, test.args);
assert.equal(res, test.expected);
});
});
});
4.debug
开发避免不了调试debug,很多人喜欢使用console.log()进行调试,这个确实蛮好用的,但是调式后如何处理console.log() 却成为了老大难的问题,注释吧,会多出很多无用的代码,删掉吧,后面可能还会使用到。
这里,我推荐使用debug模块为例:
var debug = require('debug')('myapp:main');
debug('现在的时间是 %s' , new Date());
开启debug模式(在cmd上输入): set debug = myapp:main
然后输入要执行的文件:node app.js
返回:myapp:main 现在的时间是 2018-05-03 18:25:30
关闭debug模式: set debug = null
5.配置文件书写
每个工程下都要建立一个配置文件,如config.js,而不是写死在程序里,记住接手你工作的人,是不懂你的编程逻辑的人,所以到时候你要告诉对方哪些是可配哪些是不可配,后面你会非常麻烦。
配置文件例:
{
"app": 3000,
"mongo": {
"host": "localhost",
"port": 27017
},
"redis": {
"host": "localhost",
"port": 6379
}
...
}
6.避免使用同步代码
Nodejs的一个显著特征:从上到下的设计都是为了实现异步。文件操作就有同步和异步的版本,即使使用逻辑来控制同步方法,但还是有可能不注意地用到阻塞外部的函数库。这样做,对性能影响极大。
//好的书写方式
fs.writeFile('message.txt','Hello Node',function(err) {
console.log("It's saved and the server remains responsive!");
}); //坏的书写方式(影响性能)
fs.writeFileSync('message.txt', 'Hello Node');
console.log("It's saved, but you just blocked ALL requests!");
7.不要让静态资源使用Nodejs
对于css和图片等静态资源,用标准的webserver而不是Nodejs。我们使用的是CDN来存储静态资源。
好处:
1)减少nodejs服务器的负载。
2)CDN可以让静态内容在离用户较近的服务器上传递,减少等待时间。
8.在客户端渲染
我们比较一下在客户端渲染和在服务端渲染的区别:
服务端渲染
<!DOCTYPE html>
<html>
<head>
<title>服务端渲染</title>
</head>
<body>
<div>
py1988!
</div>
</body>
</html>
客户端渲染
<!DOCTYPE html>
<html>
<head>
<title>客户端渲染</title>
</head>
<body>
<div>
<%= name %>!
</div>
</body>
</html>
javascript文本能缓存在浏览器或者本地,所有初始加载以后,唯一要发送给客户端的就是json,这是最有效的,极大减少Nodejs server的负载量。
9.并行化
试着让所有的阻塞操作并行化,这将减少阻塞操作的等待时间,为了保持回调和错误处理得干净,我们需要使用一些监控工具。
10.尽量使用二进制模块
使用二进制模块取代javascript模块(尽量);如此性能会提升一大截。
var crypto = require('crypto');
var hash = crypto.createHmac("sha1",key).update(signatureBase).digest("base64");
特殊:使用V8 javascript 取代客户端库
许多javascript库都是为了在浏览器上使用而创建的:例 一些浏览器支持 forEach,map和reduce这样的函数,但有些浏览器不支持。
V8 javascript 引擎支持Node.js实现ECMA-262第五版中指定的ECMAScript。直接用标准的V8 JavaScript函数替代客户端库,你会发现性能得到显著的提高。
Nodejs经验谈的更多相关文章
- 京东前端:PhantomJS 和NodeJS在网站前端监控平台的最佳实践
1. 为什么需要一个前端监控系统 通常在一个大型的 Web 项目中有很多监控系统,比如后端的服务 API 监控,接口存活.调用.延迟等监控,这些一般都用来监控后台接口数据层面的信息.而且对于大型网站系 ...
- NodeJs之OS
OS Node.js提供了一些基本的底层操作系统的模块OS. API var os = require('os'); console.log('[arch] 操作系统CPU架构'+os.arch()) ...
- NodeJs之Path
Path模块 NodeJs提供的Path模块,使得我们可以对文件路径进行简单的操作. API var path = require('path'); var path_str = '\\Users\\ ...
- NodeJs之调试
关于调试 当我们只专注于前端的时候,我们习惯性F12,这会给我们带来安全与舒心的感觉. 但是当我们使用NodeJs来开发后台的时候,我想噩梦来了. 但是也别泰国担心,NodeJs的调试是很不方便!这是 ...
- NodeJs在Linux下使用的各种问题
环境:ubuntu16.04 ubuntu中安装NodeJs 通过apt-get命令安装后发现只能使用nodejs,而没有node命令 如果想避免这种情况请看下面连接的这种安装方式: 拓展见:Linu ...
- NodeJs之child_process
一.child_process child_process是NodeJs的重要模块.帮助我们创建多进程任务,更好的利用了计算机的多核性能. 当然也支持线程间的通信. 二.child_process的几 ...
- nodejs进阶(6)—连接MySQL数据库
1. 建库连库 连接MySQL数据库需要安装支持 npm install mysql 我们需要提前安装按mysql sever端 建一个数据库mydb1 mysql> CREATE DATABA ...
- 图片访问实时处理的实现(nodejs和php)
我在访问时光网.网易云音乐等网站时,发现将它们页面中的一些图片URL修改一下就可以得到不同尺寸的图片,于是思考了其实现方案,我的思路是:URL Rewrite + 实时处理 + 缓存,对用户请求的UR ...
- nodejs进阶(4)—读取图片到页面
我们先实现从指定路径读取图片然后输出到页面的功能. 先准备一张图片imgs/dog.jpg. file.js里面继续添加readImg方法,在这里注意读写的时候都需要声明'binary'.(file. ...
随机推荐
- 如何在Cocos2D游戏中实现A*寻路算法(七)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...
- Opencv2.4.9、VS2010配置及grabcut代码实例
最近opencv库更新到了2.4.9,作为小码农的我紧跟时代的步伐,装了2.4.9这个库.以下是我的配置步骤: 1.从http://opencv.org/上下载opencv2.4.9文件,由于我用的是 ...
- Oracle生成查询包含指定字段名对应的所有数据表记录语句
应用场合:已知字段名字,查询数据库中所有数据表中包含该字段名的所有数据表 操作办法:指定字段名,数据库表用户,执行下面查询语句即可 --Oracle生成查询包含指定字段名对应的所有数据表记录语句 de ...
- bash:chkconfig:command not found
1尝试sudo/su rootsudo chkconfig --list2上述方法不行,请检查是否安装chkconfigrpm -qa |grep chkconfigubuntu上默认是不支持chkc ...
- polaris: 一个用go实现的支持restful的web框架
介绍 polaris是一个用go实现的支持restful的web框架,主要参考tornado进行设计. 虽然在go里面搭建一个http server非常的简单,这里强烈推荐gorilla,但并没有很好 ...
- Linux--缺页中断和交换技术
1.请求调页中断:进程线性地址空间里的页面不必常驻内存,例如进程的分配请求被理解满足,空间仅仅保留vm_area_struct的空间,页面可能被交换到后援存储器,或者写一个只读页面(COW).Linu ...
- 集群通信组件tribes之集群的平行通信
前面的集群成员维护服务为我们提供了集群内所有成员的地址端口等信息,可以通过MembershipService可以轻易从节点本地的成员列表获取集群所有的成员信息,有了这些成员信息后就可以使用可靠的TCP ...
- android 优化之布局优化
布局优化的思路很简单,尽量减少布局文件的层级,看过系统源码的都知道,Android view绘制都是逐层绘制的,所以布局的层级少了,decodeview的时候绘制工作自然就少了. 那么如何进行布局的优 ...
- Leetcode_62_Unique Paths
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/43404205 A robot is located at ...
- 对Java配置文件中敏感信息进行加解密的工具类
在 JavaEE 配置文件中,例如 XML 或者 properties 文件,由于某些敏感信息不希望普通人员看见,则可以采用加密的方式存储,程序读取后进行解密. 常见的如: 数据库用户密码,短信平台用 ...