因为打算试用一下最新的VS Code,我用npm命令安装了weak库,不过在编译的过程中出错了,看了下错误提示,不是常见依赖问题,而是一些这样的错误提示:
error C3861: '__builtin_huge_valf' : identifier not found
error C3861: '__builtin_nanf' : identifier not found
……
看上去是有一些定义没有找到,原因不详。搜索后发现问题的原因是出在我的编译器上,在Visual Sudio 2015 Update 1 里,有些函数已经被修改了宏定义,需要用以下的规则进行一下转换:
__builtin_huge_val()=HUGE_VAL
__builtin_huge_valf()=HUGE_VALF
__builtin_nan=nan
__builtin_nanf=nanf
__builtin_nans=nan
__builtin_nansf=nanf
为此,我只好把weak给clone了一份到本地来,然后修改了binding.gyp,最后用调用npm用本地安装的方式装上了这个Node.js库。
这只是一次小小的不愉快,不过根据我的经验来看,用npm进行安装时,如果代码完全是JS的库还好,如果需要进行本地编译的话,经常并不是一件省心的事。
为什么会这样?我们来看看问题出在什么地方。这里大概的对比了一下几种语言,IDE部分要能支持大型工程构建的才算,普通的TextEditor忽略。
语言 | 运行环境 | 标准提供者 | 语言实现 | 编译环境 | IDE |
Java | JRE (Oracle) | JCP or Oracle | Oracle or OpenJDK |
javac -> class,跨平台
|
Eclipse
NetBean
等等
|
C# | .Net FrameWork (Mirsoft) | Microsoft | Microsoft or Mono | csc -> dll,跨平台 | VS (Microsoft) |
Rust | None | Mozilla | Mozilla | rustc -> rlib,不同平台分别编译 |
None
|
Node.js
| node (Node.js.org) | ECMAScript (ECMA) | V8 (Google) | C++编译器(VC、GCC),不同平台分别编译 | None |
可以看到,Node.js的构成体系过于分散。语言的标准是ECMA制定的,核心引擎是Google提供的,编译环境又依赖不同平台的C++编译器,而核心的库函数是Node.js.org提供的。这样的混乱的结构就决定了每一个环境有重大技术更新的时候,对Node.js来说都无疑是一场灾难,对于Node.js开发者来说,始终处在一个充满变数不可预知的环境中。
注:此文写完不久后,就发生了left-pad模块被unpublish导致众多项目无法正常构建的事情。
IDE也是Node.js的硬伤,没有完善的系统工程,很难开发出支持大型项目的IDE,JS的语法特点又决定了代码提示、重构这些IDE必须的功能都很难在项目这一级别实现,也无法在编译期排除语义上的错误,这就导致很多错误只能在运行期才会被发现,对于无法稳定重现的错误也很难定位。
如果没有Eclipse、JBuilder、Visual Studio这样的IDE支持,就不可能会有那么多C++/Java/C#的大型项目出现。在系统化的工程里,要用工具来弥补人的不足,保证代码和项目的可靠性。而你在用Sublime编写Node.js程序的时候,写错了一个属性名,不会有任何的错误提示,代码也能运行起来,只不过得到的并不是你想要的结构(动态语言的通病)。你很难想像10人以上的团队用Node.js来写一个大型的工程——如果有的话,那肯定是一团糟,不要说做一次大型的重构,改一个字段名(特别是多个类都可能有同样字段命名的情况下)有可能都是一件大工程。
总而言之,Node.js虽然借了JavaScript的东风,吸引了无数的工发者,但是从长远来看,它并不是一个良好的技术方向,注定会淹没在技术革新的浪潮中。
顺便聊下,什么样的语言才是好的语言呢?人个认为它需要有以下优秀的气质:
* 不依赖GC
* 语义清晰,不要有过多的语法糖和小众的书写方式
* 便于优化,特别是和LLVM这样的引擎配合,对平台的依赖少,支持JIT
* 完整的工具链,包括:依赖管理、项目管理、IDE、标准格式还有其它。。。
在M$收购了Mono后,C#的发展方向可以期待一下。GoLang,Rust,Nim 还在演化中,当然还有Swift。