====== NodeJS/Javascript ====== News: * [[https://nodejs.org/en/blog/release/v18.0.0|node 18.0]] * [[https://nodejs.org/en/blog/release/v16.0.0/|node 16.0]] * [[https://nodejs.org/en/blog/release/v10.0.0/|node 10.0]] * [[https://nodejs.org/en/blog/release/v8.0.0/|node 8.0]] * [[https://nodejs.org/en/blog/release/v6.0.0/|node 6.0]] * [[https://cnodejs.org/topic/55efcc524b70f72113ff4f3b|nodejs 4.0]] * [[http://blog.nodejs.org/2015/02/06/node-v0-12-0-stable/|node-v0-12-0-stable]] * [[https://github.com/joyent/node/wiki/API-changes-between-v0.10-and-v0.12|API-changes-between-v0.10-and-v0.12]] [[https://github.com/creationix/nvm|Nodejs版本选择与快速安装利器NVM,适用开发环境]] * [[http://nodejs.org|Official site]] * [[http://blog.fens.me/series-nodejs/|从零开始系列文章]] * [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference|Mozilla JS reference]] * [[http://javascript.ruanyifeng.com/|阮一峰的js教程]] * [[http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html|深入理解JavaScript系列]] * [[http://www.infoq.com/cn/articles/generator-and-asynchronous-programming|Generator and asynchronous programming]] * [[Typescript]] * Nodejs v4.0.0 之后的版本需要 gcc 4.7版本以上来进行 addon 编译. GCC 4.7 or newer is required due to V8 using the template alias feature in C++. ===== 1. V8 GC ===== * [[https://github.com/thlorenz/v8-perf|thlorenz/v8-perf]] * {{:public:it:speakerdeck-_memory_management_masterclass_devtools_2_.pdf|memory_management.pdf}} * [[http://huang-jerryc.com/2016/04/14/NodeJS%E4%B8%AD%E8%A2%AB%E5%BF%BD%E7%95%A5%E7%9A%84%E5%86%85%E5%AD%98/|NodeJS 内存]] * [[https://blog.appsignal.com/2022/09/28/minimize-heap-allocations-in-nodejs.html|Minimize heap allocations in nodejs]] ===== 2. ECMAScript ===== * [[http://ecmascript.org|Official site]] * 目前各大浏览器的JS实现符合ES5.1版;ES6的[[http://kangax.github.io/compat-table/es6/|实现情况]] * [[http://es6.ruanyifeng.com|阮一峰的es6入门]] * nodejs 0.11.* 实现部分es6特性, 要使用需要加上''--harmnoy'' * [[https://nodejs.org/en/docs/es6/|ES6 on nodejs]] ---- ===== 3. Packages ===== * [[https://github.com/sindresorhus/awesome-nodejs|awesome-nodejs]] 这里可以分类查找你想要的库! ==== ›› Modules ==== * commonjs [[http://wiki.commonjs.org/wiki/Modules/1.0|Modules/1.0]] * [[http://nodejs.org/api/modules.html| modules doc]] **modules cycles 注意关于模块互相包含的处理机制** ==== ›› npm or yarn==== * [[https://www.npmjs.com/|npm]] * [[https://docs.npmjs.com/files/package.json|package.json]] * npm 使用国内淘宝源 npm config set registry https://registry.npmmirror.com # 配置后可通过下面方式来验证是否成功 npm config get registry npm get registry npm info webpack # 恢复 npm config rm registry * [[https://yarnpkg.com/zh-Hans/|yarn]]: 更快更安全 * [[https://pnpm.io/motivation|pnpm]]: 可节省硬盘空间 ==== ›› pm2 ==== * [[https://github.com/Unitech/pm2|pm2]] nodejs进程管理工具, 可 * 进程运行状态监测,进程重启 * 管理进程集群 * 超过指定内存则重启 * 文件改动则重启 ==== ›› rxjs ==== * [[https://github.com/ReactiveX/rxjs|github repo]] * [[https://rxjs.dev/guide/overview|overview]] * [[https://rxjs.dev/guide/observable|observable]] 这个要熟读并理解 ==== ›› async ==== * [[https://github.com/caolan/async|async]] * [[https://github.com/bsspirit/async_demo|async demo]] * [[http://zhangqi.im/webdevelopment/nodejsasyncone.html|部分介绍]] * [[http://blog.fens.me/nodejs-async/|全面一点的]] ==== ›› promise ==== * [[http://www.thinkingincrowd.me/2013/11/13/callbacks-are-imperative/|Callbacks are imperative]] (async)回调风格是显式的控制处理流程来把很多值组织在一起,而 promises 是显式表达出值的关系来把控制流的各个组件连接在一起。回调是指令式的,promises 是函数式的 * [[https://jysperm.me/2016/10/nodejs-error-handling/|引自这篇文章:]]如果有异常没有捕捉到怎么样?如果有一个异常一直被传递到最顶层调用栈还没有被捕捉,那么就会导致进程的崩溃退出,不过我们还有两个终极捕捉手段: process.on('uncaughtException', (err) => { console.error(err); }); ''uncaughtException'' 事件可以捕捉到那些已经被抛出到最顶层调用栈的异常,一旦添加了这个监听器,这些异常便不再会导致进程退出。实际上有一些比较激进的人士认为程序一旦出现事先没有预料到的错误,就应该立刻崩溃,以免造成进一步的不可控状态,也为了提起开发人员足够的重视。但我从比较务实的角度建议还是不要这样做,尤其是服务器端程序,一个进程崩溃重启可能需要一分钟左右的时间,这段时间会造成服务的处理能力下降,也会造成一部分连接没有被正确地处理完成,这个后果很可能是更加严重的。但我们应当将在这个事件中捕捉到的错误视作非常严重的错误,因为在此时已经丢失了和这个错误有关的全部上下文,必然无法妥善地处理这个错误,唯一能做的就是打印一条日志。 process.on('unhandledRejection', (reason, p) => { console.error(reason, p); });''unhandledRejection'' 事件可以捕捉到那些被 reject 但没有被添加 .catch 回调的 Promise, 通常是因为你忘记为一个返回 Promise 的函数添加 return。因为 Promise 本来就是对异步错误的一种封装,所以实际使用中偶尔也会出现 Promise 先被 reject, 而后再用 .catch 添加错误处理的情况,所以这个事件实际上偶尔会有误报。 * 对数组或对象或map进行顺序的异步任务时,可以这样 //要得到一个then then then的promise链,先定义一个已经resolve了的promise,然后依次往后then… var sequence = Promise.resolve(); array.forEach(function(item) { sequence = sequence.then(...) }); ==== ›› express ==== * 4.0 开始 express 废弃 connect, 默认的文件上传插件''multer''需要手动引入 ==== ›› winston ==== * [[https://github.com/flatiron/winston | Homepage]] * Console 默认不以json格式记录, File默认以json格式记录, 可以用''json:true/false''来修改 * ''prettyPrint'' 会把object或json展开成多行, 利于肉眼观察不利于grep分析 ==== ›› moment ==== * 坑!moment如果使用object构造, 其中参数月份的值范围是0~11, 而其它构造方式是1~12; * 改用 day.js ==== ›› http-server ==== * 使用方便的静态http服务 ''sudo npm i http-server -g'' 安装, 之后使用''http-server''命令来启动静态网站. ==== ›› 一些好用的库 ==== * [[https://www.npmjs.com/package/shelljs|shelljs]] * [[https://www.npmjs.com/package/inquirer|inquirer]] 超好用的命令行界面库 * [[https://www.npmjs.com/package/clui|clui ]] 好用的命令行显示控件,包括进度条,等待转圈等。 * [[https://www.npmjs.com/package/figlet|figlet]] ascii字符图形 ==== ›› tips ==== * node-gyp 提示错误''/home/you/.node-gyp/0.10.26/common.gypi not found'',原因可能是上一次失败引起,直接删除''.node-gyp''整个文件夹迫使其重新编译即可。 * :!: node 从 0.12 版本开始, ''socket.remoteAddress'' 的 IP 显示格式就变成了 IPv6 格式, 比如IP ''10.11.13.3'' 变为 ''::ffff:10.11.13.3'' * 清屏 /** 清屏 */ process.stdout.write('\x1b[2J'); /** 移动光标到左上角 */ process.stdout.write('\x1b[0f'); ===== 4. 代码规范 ===== * [[https://github.com/airbnb/javascript|airban js style-guide]] * [[https://github.com/felixge/node-style-guide|Node style guide]] 不符合我习惯啊 * [[https://www.joyent.com/developers/node/design/errors| Error handling]] ===== 5. 项目瘦身 ===== * nodejs项目在''npm i ''之后, 会留下大量冗余的文件与中间编译文件 * 使用''npm ddp''来对单项目下的重复包进行冗余去除 * 对于多个项目, 把各个项目的node_modules移动到上层同一目录node_modules下, 去除单层重复包 * 部分包使用了gyp编译, 可去除其中间文件 * 去除各种冗余文件或文件夹, 比如"test" "example" "readme" "*.md" ".*ignore" ".travis.yml" "benchmark*" 等等. ---- ===== 6. Syntax ===== ==== 6.1 New ==== * [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new | new operation description on mozillla.org]] * [[http://stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript | What is the new keyword in javascript]]: It is 4 things: It creates a new object. The type of this object, is simply object. It sets this new object's internal, inaccessible, [[prototype]] property to be the constructor function's external, accessible, prototype object (every function object automatically has a prototype property). It executes the constructor function, using the newly created object whenever this is mentioned. It returns the newly created object, unless the constructor function returns a non-primitive value. In this case, that non-primitive value will be returned. new 相当于 function New(func) { var res = {}; if (func.prototype !== null) { res.__proto__ = func.prototype; } var ret = func.apply(res, Array.prototype.slice.call(arguments, 1)); if ((typeof ret === "object" || typeof ret === "function") && ret !== null) { return ret; } return res; } 所以 ''var sth = new func()''时, func()返回值而不是引用时, sth是func对象的新对象, 如果返回值为引用, 则sth为该引用. ==== 6.2 JS的原型链 ==== {{ :public:it:javascript_object_layout.jpg?nolink |}} ==== 6.3 Tips ==== * 以变量为变量名'' var name = 'some'; global[some] = 'thing' '', ''var name = 'some'; var name2={}; name2[name]='thing' '' * 删除子对象 ''var obj = {name:'some',des:'thing'}; delete obj.des; '';删除对象则直接''obj=null'' 会自动回收。 * 逻辑运算符“||”与“&&”,也遵循短路原则,但与其它很不同的一点是,其返回值并不是bool, 而是条件参 var name = 'some' && 'thing'; //name == 'thing' var name = false || 'thing'; //name == 'thing' var name = false && 'thing'; //name == false * 对象的 clone : var old = {a: 1, b: 2}; var new = Object.assign({}, old);// 可能不适用IE * 如果文件 tt.log 被 ''fs.createWriteStream'' 以 ''w+'' 的方式打开, 那么中途在另一进程里 ''truncate -s0 tt.log'' 之后, 文件流仍然会继续在之前的位置写入 tt.log , 导致 tt.log 大小仍保持原大小,第一行变成了原长度的乱码。 所以有定期 truncate 的文件在写入时一定要使用 ''a+'' 的方式来打开流。 详见 ''man fopen''. **所以使用 forever-monitor 这个库时一定记得加上参数 ''append:true'', 具体见库源码.** * 如果字符串与数字比较,字符串会被转换成数字再进行比较: console.log('9.99' > '10.00'); // true, => '9' > '1' console.log('9.99' > 10.00); // false, => 9.99 < 10.00 console.log('wtf9.99' > 10.00);// false, => 9.99 < 10.00 ===== 7. Debug ===== * ''console.log()'' * [[https://github.com/node-inspector/node-inspector|Node Inspector]]