第1312期Node.js开发之父:十个Node.js的设计错误以及其终极解决办法

Posted 前端早读课

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第1312期Node.js开发之父:十个Node.js的设计错误以及其终极解决办法相关的知识,希望对你有一定的参考价值。

前言

今日早读文章由@David Ng、@Starkwang分享。

正文从这开始~

养不教,父之过。Node.js 创始人 @Ryan Dahl 在 JSconf 2018点评了十个在设计和更新Node.js时犯下的错误。

2008年Chrome才刚刚出现,现在已经更新到了版本66.0了。而Node.js其实也是近十年冒起的代表。它只是2009年的产物,现在出到版本10,却在软件界家喻户晓。

不过有用过Node.js作为production 的工程师,应该很同意Node.js其中一个重要的特征就是:内存泄漏。所以在实际开发时,往往都要用forever来自动定时重启Node.js Server。

很多底层的设计错误

要了解这些错误以其重要性,可能要对程序设计语言和软件工程有深入点的认识。Ryan Dahl在Node.js中的设计和应用,直接或间接影响了不少重要的软件,甚至整个软件行业。因为有不少软件和平台都以Node为根基。

Ryan Dahl在演讲中用了个很严重的说法指出:

动态语言适合与一次性的科学演算,而javascript就是最好的例子。
不然,Node中充满着投诉的缺陷。

真的是相当严重的懊悔。因此,他以Design mistakes in Node为题,指出了十个悔不当初的错误。

后悔之一:没有坚持使用Promise

在2009年6月,Node中开始引入Javascript的Promise,但在2010年2月就移除掉了。

结果,随着日子久远,Node里面就遍布着async/await 和 promise的不同 异步API的设计,直至现在都极难整合。

后悔之二:看轻了安全性

JavaScript Engine V8 本身有很好的sandbox架构,但是有时候Node.js本身没有好好利用,例如有可以直接读取Memory的例子,或者 linter 可以直接使用网络功能等的漏洞。

后悔之三:没有从GYP构建系统转到GN

Node.js用到的Javascript Engine V8 一开始是使用GYP构建的,Node理所当然也跟随,后来V8转用了GN(Generate Ninja),只剩下Node成为唯一的用户。GN比用Python写的GYP快接近20倍,对于使用者来说,简直就是天澜之别。

Ryan更这样说:

继续适用GYP该是Node核心的最大失误。

后悔之四:继续使用GYP,没有提供FFI

继续用GYP引申到另一个难题,就是怎么样去提供跨程序语言的接口。

现在Node只提供了由C++到V8的binding指南,事实上对开发者来说是严重不足的,很多人建议过转用Foreign Function Interface (FFI)的模式,但都一一被当时的Ryan忽略了。

后悔之五:package.json以及依赖了npm

npm的Issac发明了package.json,Ryan认为把Node能在main program中用require()读取npm的package.json 是一个坏的开始。

后来,演化至Node中包含npm作为标准,以至现在Node的Module变成了由npm集权了。

事实上,因为npm而引起的灾难性事件也不少,其中最有名的应该算2016年发生的left-pad chaos。

后悔之六:在任何地方也可以require(“somemodule”)


你可以不必在package.json中注明dependency,在Node中几乎是任何地方也能够require local 或者是 remote的程序代码。

后悔之七:package.json 提供了错误的module 概念

你以为放在同一个文件夹里的就是一个module了,少年你还是太年轻了。其实并没有这样的一个机制。

其实现在package.json 并没有公认标准,里面可以包含很多毫无关系的信息,比如名称、版本、License、详细说明等,以致package.json 整个文件像是杂物间一样。

例如我们用URL导入项目的话,URL里就以包含了所需的版本信息,而不应再写在package.json里。

后悔之八:设计了软件界黑洞node_modules

有试过npm之后,要等很久,然后发现项目下载了几百MB的node_module吗?

这是因为Node里Vendored-by-default机制有点好心办坏事。从而令node_module主动地安装了所有module的dependencies。这个设计另要处理node_module的方式变得超复杂,也变成Node里面最令人苦恼的一个地方。

Ryan 对这个设计应该是彻底地后悔。

這是我的錯-十分抱歉。不幸的是,現在已經無法砍掉了。

后悔之九:require(“module”)没有逼人用文件扩展名.js

不知道为什么要这样的简洁。

在浏览器中<script> 标签是不能省略.js部分的,这令Node要多用几次不必要的查询,才能猜到工程师想要引入什么文件。

后悔之十:index.js

由于index.html 的传统,很合理有inde.js吧?但其实有了package.json后,index.js就变得不必要了。

结论

Node.js现在遇到的问题,其实大多上都是软件管理上的问题,例如API、FFI,引入文件的方案和dependency管理上的痛苦。

结果呢,Ryan针对以上的反思,提出了一个方案,就是开发以安全性、程序代码简洁性,符合2018年标准为原则的框架 - deno。

deno是以Golang + yarn + TS 为主要的技术栈,舍弃了Node.js 本来C++ 和Javascript。deno暂时还是在初步阶段,要试玩的话,还是要由
source code 自行编译。

不过,Ryan 看来相当满意deno暂时的设计,起码应该不会犯和Node 相同的错误了。

其实,deno并不是想要直接取代Node.js的,而是提出了一个新的框架去协助工程师去构建未来更加合理的软件。

关于deno,在2018-06-13,Ryan 发布了 deno 的第二版原型,主要的变化有:

  • 使用 GN 这个构建工具,这是 chromium 团队使用的构建工具

  • 使用 V8 Snapshots 提升启动速度(之前其实就提到过了)

  • 移除 Golang,因为不想同时存在两个 GC(Go和TS)

  • 弄了一个 C++ 库叫 libdeno,负责 TS 的运行时环境

ry 还提到未来可能会考虑把目前的 C++ 改写成 Rust

PPT:http://tinyclouds.org/jsconf.pdf
视频:https://www.youtube.com/watch?v=M3BM9TB-8yA

https://zhuanlan.zhihu.com/p/38071588

以上是关于第1312期Node.js开发之父:十个Node.js的设计错误以及其终极解决办法的主要内容,如果未能解决你的问题,请参考以下文章

[第12期] Node.js Web开发

Domino 情报站 | 第1期 与 JavaScript 和 Node.js “组团开黑”

第1768期Node.js 在微医的应用场景及实践

第1275期基于node.js平台的脚手架开发经历

第1523期Node.js 中的依赖管理

第1496期新手向之Vue.js + Node.js(koa) 合体指南