buk*_*zor 26 javascript require google-closure-compiler node.js
是否有任何项目一起使用node.js和closure-compiler(简称CC)?
CC的官方建议是一起编译应用程序的所有代码,但是当我编译一些包含a的简单node.js代码时require("./MyLib.js"),该行直接放入输出中,但在该上下文中没有任何意义.
我看到几个选项:
bol*_*est 50
我一直在使用Closure Compiler with Node来完成我尚未发布的项目.它采用了一些工具,但它有助于捕获许多错误,并且具有非常短的编辑 - 重启 - 测试周期.
首先,我使用plovr(这是我创建和维护的项目),以便一起使用Closure Compiler,Library和Templates.我以Closure Library的样式编写Node代码,因此每个文件都定义了自己的类或实用程序集合(如goog.array).
下一步是为要使用的Node函数创建一组externs文件.我公开发表了一些这些内容:
https://github.com/bolinfest/node-google-closure-latitude-experiment/tree/master/externs/node/v0.4.8
虽然最终,我认为这应该是一个更加社区驱动的东西,因为有很多功能需要记录.(这也很烦人,因为一些Node函数有可选的中间参数而不是最后一个参数,使得类型注释变得复杂.)我自己没有开始这个动作,因为我们可以用Closure Complier做一些工作来减少它的尴尬(见下文).
假设您已为Node命名空间创建了externs文件http.在我的系统中,我已经决定,只要我需要http,我将通过以下方式包含它:
var http = require('http');
Run Code Online (Sandbox Code Playgroud)
虽然require()我的代码中没有包含该调用.相反,我使用output-wrapperClosure Compiler 的功能,在require()文件开头添加所有s,在plovr中声明,在我当前的项目中如下所示:
"output-wrapper": [
// Because the server code depends on goog.net.Cookies, which references the
// global variable "document" when instantiating goog.net.cookies, we must
// supply a dummy global object for document.
"var document = {};\n",
"var bee = require('beeline');\n",
"var crypto = require('crypto');\n",
"var fs = require('fs');\n",
"var http = require('http');\n",
"var https = require('https');\n",
"var mongodb = require('mongodb');\n",
"var nodePath = require('path');\n",
"var nodeUrl = require('url');\n",
"var querystring = require('querystring');\n",
"var SocketIo = require('socket.io');\n",
"%output%"
],
Run Code Online (Sandbox Code Playgroud)
通过这种方式,我的库代码从不调用Node require(),但编译器可以容忍http我的代码中使用的东西,因为编译器将它们识别为externs.由于它们不是真正的外部因素,因此必须按照我的描述进行.
最后,在讨论列表中讨论了这个之后,我认为更好的解决方案是为命名空间创建一个类型的新类型注释:
goog.scope(function() {
/** @type {~NodeHttpNamesapce} */
var http = require('http');
// Use http throughout.
});
Run Code Online (Sandbox Code Playgroud)
在这种情况下,externs文件将定义NodeHttpNamespaceClosure Compiler能够使用externs文件对其进行类型检查.这里的区别在于您可以为require()任何您想要的返回值命名,因为类型http将是这种特殊的命名空间类型.(识别"jQuery命名空间" $是一个类似的问题.)这种方法将不再需要一致地命名Node命名空间的局部变量,并且不需要output-wrapperplovr配置中的那个巨人.
但这是一个题外话......一旦我按照上面所述设置了东西,我就有了一个shell脚本:
RAW模式构建所有内容.node由plovr生成的文件.使用RAW模式会导致所有文件的大量连接(尽管它还负责将Soy模板甚至CoffeeScript转换为JavaScript).不可否认,这使得调试变得很痛苦,因为行号是无稽之谈,但到目前为止我一直运作良好.Closure Compiler执行的所有检查都使它值得.
Ray*_*nos -29
选项 4:不使用闭包编译器。
节点社区的人不倾向于使用它。您不需要缩小 node.js 源代码,这很愚蠢。
缩小根本没有什么好处。
至于闭包的性能优势,我个人怀疑它实际上会让你的程序更快。
当然这是有代价的,调试已编译的 JavaScript 是一场噩梦